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])) [else +inf.0]))
(for/list ([i (in-naturals)] (for/list ([i (in-naturals)]
#:break (or (eof-object? (peek-byte port)) (= (pos port) end-pos))) #: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 ;; we have len, which is treated as count of items
[else (for/list ([i (in-range len)]) [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]) (define/augride (:encode array port [parent #f])
(unless (sequence? array) (unless (sequence? array)

@ -178,7 +178,7 @@ https://github.com/mbutterick/restructure/blob/master/src/Number.coffee
(super-new) (super-new)
(init-field [(@fracbits fracbits)]) (init-field [(@fracbits fracbits)])
(unless (exact-positive-integer? @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)) (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)) (define orig-pos (pos port))
(pos port ptr) (pos port ptr)
(begin0 (begin0
(send @type :decode port parent) (send @type decode port parent)
(pos port orig-pos))) (pos port orig-pos)))
(if @pointer-lazy? (delay (decode-value)) (decode-value))] (if @pointer-lazy? (delay (decode-value)) (decode-value))]
[else ptr])])) [else ptr])]))

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

@ -2,6 +2,7 @@
(require rackunit (require rackunit
racket/class racket/class
"../array.rkt" "../array.rkt"
"../struct.rkt"
"../number.rkt" "../number.rkt"
"../pointer.rkt" "../pointer.rkt"
"../base.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))]) (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)))) (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 (test-case
"array: decode with post-decode" "array: decode with post-decode"
(parameterize ([current-input-port (open-input-bytes (bytes 1 2 3 4 5))]) (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)) (decode (x:struct 'name (x:string #:length uint8) 'age uint8))
(mhasheq 'name "roxyb" 'age 21)))) (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 (test-case
"struct: decode with process hook" "struct: decode with process hook"
(parameterize ([current-input-port (open-input-bytes #"\x05roxyb\x20")]) (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"))]) (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))))) (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 (test-case
"versioned struct: decode should throw for unknown version" "versioned struct: decode should throw for unknown version"
(let ([vstruct (x:versioned-struct uint8 (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)])) (raise-argument-error 'x:versioned-struct-decode (format "valid field version: ~v" (dict-keys @versions)) which-version)]))
(match field-object (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)])) [_ (parse-fields port res field-object)]))
(define/override (:encode field-data port [parent-arg #f]) (define/override (:encode field-data port [parent-arg #f])

Loading…
Cancel
Save