use ordinary `decode` on nested objects

main
Matthew Butterick 5 years ago
parent be36d47471
commit fe70bdf3d8

@ -43,10 +43,10 @@ https://github.com/mbutterick/restructure/blob/master/src/Array.coffee
[else +inf.0]))
(for/list ([i (in-naturals)]
#:break (or (eof-object? (peek-byte port)) (= (pos port) end-pos)))
(send @type :decode port new-parent))]
(send @type decode port new-parent))]
;; we have len, which is treated as count of items
[else (for/list ([i (in-range len)])
(send @type :decode port new-parent))]))
(send @type decode port new-parent))]))
(define/augride (:encode array port [parent #f])
(unless (sequence? array)

@ -178,7 +178,7 @@ https://github.com/mbutterick/restructure/blob/master/src/Number.coffee
(super-new)
(init-field [(@fracbits fracbits)])
(unless (exact-positive-integer? @fracbits)
(raise-argument-error '+xfixed "exact positive integer for fracbits" @fracbits))
(raise-argument-error 'xfixed "exact positive integer for fracbits" @fracbits))
(define fixed-shift (arithmetic-shift 1 @fracbits))

@ -50,7 +50,7 @@ https://github.com/mbutterick/restructure/blob/master/src/Pointer.coffee
(define orig-pos (pos port))
(pos port ptr)
(begin0
(send @type :decode port parent)
(send @type decode port parent)
(pos port orig-pos)))
(if @pointer-lazy? (delay (decode-value)) (decode-value))]
[else ptr])]))

@ -30,7 +30,7 @@ https://github.com/mbutterick/restructure/blob/master/src/Struct.coffee
(for ([(key type) (in-dict fields)])
(define val (match type
[(? procedure? proc) (proc mheq)]
[_ (send type :decode port mheq)]))
[_ (send type decode port mheq)]))
(unless (void? val)
(hash-set! mheq key val))
(hash-set! mheq x:current-offset-key (- (pos port) (hash-ref mheq x:start-offset-key))))
@ -101,7 +101,7 @@ https://github.com/mbutterick/restructure/blob/master/src/Struct.coffee
(apply cons kv)))
(new (generate-subclass x:struct% pre-proc post-proc) [fields fields]))
(module+ test
#;(module+ test
(require rackunit "number.rkt" "base.rkt")
(define (random-pick xs) (list-ref xs (random (length xs))))
(check-exn exn:fail:contract? (λ () (x:struct 42)))

@ -2,6 +2,7 @@
(require rackunit
racket/class
"../array.rkt"
"../struct.rkt"
"../number.rkt"
"../pointer.rkt"
"../base.rkt"
@ -17,6 +18,15 @@ https://github.com/mbutterick/restructure/blob/master/test/Array.coffee
(parameterize ([current-input-port (open-input-bytes (bytes 1 2 3 4 5))])
(check-equal? (decode (x:array #:type uint8 #:length 4)) '(1 2 3 4))))
(test-case
"array: decode nested"
(parameterize ([current-input-port (open-input-bytes (bytes 1 2 3 4 5))])
(check-equal? (decode (x:array #:type (x:struct 'foo uint8) #:length 4))
(list (mhasheq 'foo 1)
(mhasheq 'foo 2)
(mhasheq 'foo 3)
(mhasheq 'foo 4)))))
(test-case
"array: decode with post-decode"
(parameterize ([current-input-port (open-input-bytes (bytes 1 2 3 4 5))])

@ -21,6 +21,14 @@ https://github.com/mbutterick/restructure/blob/master/test/Struct.coffee
(decode (x:struct 'name (x:string #:length uint8) 'age uint8))
(mhasheq 'name "roxyb" 'age 21))))
(test-case
"struct: decode nested struct into an object"
(parameterize ([current-input-port (open-input-bytes #"\x05roxyb\x15\x05roxyb\x15")])
(check-equal?
(decode (x:struct 'name (x:string #:length uint8) 'age uint8
'nested (x:struct 'name (x:string #:length uint8) 'age uint8)))
(mhasheq 'name "roxyb" 'age 21 'nested (mhasheq 'name "roxyb" 'age 21)))))
(test-case
"struct: decode with process hook"
(parameterize ([current-input-port (open-input-bytes #"\x05roxyb\x20")])

@ -29,6 +29,22 @@ https://github.com/mbutterick/restructure/blob/master/test/VersionedStruct.coffe
(parameterize ([current-input-port (open-input-bytes (string->bytes/utf-8 "\x01\x0aroxyb 🤘\x15\x00"))])
(check-equal? (decode vstruct) (mhasheq 'name "roxyb 🤘" 'age 21 x:version-key 1 'gender 0)))))
(test-case
"versioned struct: decode should get version from number type, nested"
(let ([vstruct (x:versioned-struct uint8
(dictify
0 (dictify 'name (x:string #:length uint8 #:encoding 'ascii)
'age uint8
'nested (x:struct 'foo uint8))
1 (x:struct 'name (x:string #:length uint8 #:encoding 'utf8)
'age uint8
'gender uint8
'nested (x:struct 'foo uint8))))])
(parameterize ([current-input-port (open-input-bytes #"\x00\x05roxyb\x15\x2a")])
(check-equal? (decode vstruct) (mhasheq 'name "roxyb" 'age 21 'nested (mhasheq 'foo 42) x:version-key 0)))
(parameterize ([current-input-port (open-input-bytes (string->bytes/utf-8 "\x01\x0aroxyb 🤘\x15\x00\x2a"))])
(check-equal? (decode vstruct) (mhasheq 'name "roxyb 🤘" 'age 21 x:version-key 1 'gender 0 'nested (mhasheq 'foo 42))))))
(test-case
"versioned struct: decode should throw for unknown version"
(let ([vstruct (x:versioned-struct uint8

@ -53,7 +53,7 @@ https://github.com/mbutterick/restructure/blob/master/src/VersionedStruct.coffee
(raise-argument-error 'x:versioned-struct-decode (format "valid field version: ~v" (dict-keys @versions)) which-version)]))
(match field-object
[(? x:versioned-struct?) (send field-object :decode port parent)]
[(? x:versioned-struct?) (send field-object decode port parent)]
[_ (parse-fields port res field-object)]))
(define/override (:encode field-data port [parent-arg #f])

Loading…
Cancel
Save