Commits

Thomas Chust committed 2070c33 Draft

Allow message merging during deserialization

Comments (0)

Files changed (2)

 (define ((appender accessor mutator) msg v)
   (mutator msg (append (accessor msg null) (if (list? v) v (list v)))))
 
-(define (deserialize type [port (current-input-port)])
-  (let ([info (force (protobuf-ref type))])
-    (letrec ([msg ((message-info-constructor info))]
+(define (deserialize type/msg [port (current-input-port)])
+  (let ([info (force (protobuf-ref type/msg))])
+    (letrec ([msg (if (struct-type? type/msg) ((message-info-constructor info)) type/msg)]
              [fields (message-info-fields info)]
              [required (message-info-required info)]
              [unknown (open-output-bytes)])
                       msg
                       (cond
                         [(eq? type 'sized)
-                         (read-sized (cut deserialize stype <>) port)]
+                         (let ([proto
+                                (if repeated?
+                                    stype
+                                    (let ([proto (accessor msg)])
+                                      (if (void? proto) stype proto)))])
+                           (read-sized (cut deserialize proto <>) port))]
                         [else
                          (let-values ([(line1 col1 pos1) (port-next-location port)])
                            (raise-read-error
 
 (provide/contract
  [deserialize
-  (->* (struct-type?)
+  (->* ((or/c struct-type? struct?))
        (input-port?)
        any)]
  [serialize

scribblings/main.scrbl

   
 }
 
-@defproc[(deserialize [type struct-type?] [in input-port? (current-input-port)]) any/c]{
+@defproc[(deserialize [type/msg (or/c struct-type? struct?)] [in input-port? (current-input-port)]) any/c]{
 
-  Read an instance of @racket[type] encoded in protocol buffer format
-  from the port @racket[in]. @racket[type] must represent a protocol
-  buffer message type.
+  Read a structure instance encoded in protocol buffer format from the
+  port @racket[in]. @racket[type/msg] can either represent a protocol
+  buffer message type or be an existing protocol buffer message that
+  will be destructively merged with the newly read data.
 
 }