You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
typesetting/pitfall/restructure/string.rkt

47 lines
1.5 KiB
Racket

#lang restructure/racket
(require "number.rkt" "utils.rkt" "stream.rkt")
(provide (all-defined-out))
#|
approximates
https://github.com/mbutterick/restructure/blob/master/src/String.coffee
|#
(struct $codec (encoder decoder) #:transparent)
(define-subclass Streamcoder (String [strlen #f] [encoding 'ascii])
(field [codec (caseq encoding
[(latin-1 ascii) ($codec string->bytes/latin-1 bytes->string/latin-1)]
[(utf-8 utf8) ($codec string->bytes/utf-8 bytes->string/utf-8)])])
(define/augment (decode stream [parent #f])
(define count (if strlen
(resolveLength strlen stream parent)
(send stream length)))
(define bytes (send stream read count))
(($codec-decoder codec) bytes))
(define/augment (encode stream val [parent #f])
(define bytes (($codec-encoder codec) (format "~a" val)))
(when (Number? strlen) ;; length-prefixed string
(send strlen encode stream (bytes-length bytes)))
(send stream write bytes))
(define/override (size [str-in #f])
(define str (or str-in (make-string strlen #\x)))
(define es (+EncodeStream))
(encode es str)
(bytes-length (send es dump))))
(test-module
(require "stream.rkt")
(define stream (+DecodeStream #"\2BCDEF"))
(define S (+String uint8 'utf8))
(check-equal? (send S decode stream) "BC")
(define os (+EncodeStream))
(send S encode os "Mike")
(check-equal? (send os dump) #"\4Mike")
(check-equal? (send (+String) size "foobar") 6))