ddat interop with dat js cable interop with cabal js ddat's frontend = dat-thang cable fe = cable-thang dillo support based on cel's dillo-dat bootstrap node xplatform support Signed-off-by: divo <418@cryspace.space>
43 lines
1.8 KiB
Scheme
43 lines
1.8 KiB
Scheme
;;; Shared record conventions for Scheme-facing Dat APIs.
|
|
;;; A record is (tag (field . value) ...); payload bytes stay bytevectors.
|
|
|
|
(define (dat:record? value . wanted-tag)
|
|
(and (pair? value)
|
|
(symbol? (car value))
|
|
(or (null? wanted-tag) (eq? (car value) (car wanted-tag)))
|
|
(let loop ((fields (cdr value)) (seen '()))
|
|
(if (null? fields)
|
|
#t
|
|
(and (pair? fields)
|
|
(pair? (car fields))
|
|
(symbol? (caar fields))
|
|
(not (memq (caar fields) seen))
|
|
(loop (cdr fields) (cons (caar fields) seen)))))))
|
|
|
|
(define (dat:record-ref record field . fallback)
|
|
(if (not (dat:record? record))
|
|
(error 'wrong-type-arg "expected a Dat record" record)
|
|
(if (not (symbol? field))
|
|
(error 'wrong-type-arg "record field name must be a symbol" field)
|
|
(let ((entry (assq field (cdr record))))
|
|
(if entry
|
|
(cdr entry)
|
|
(if (pair? fallback) (car fallback) #f))))))
|
|
|
|
(define (dat:record-set record field value)
|
|
(if (not (dat:record? record))
|
|
(error 'wrong-type-arg "expected a Dat record" record)
|
|
(if (not (symbol? field))
|
|
(error 'wrong-type-arg "record field name must be a symbol" field)
|
|
(let loop ((fields (cdr record)) (reversed '()) (found #f))
|
|
(if (null? fields)
|
|
(cons (car record)
|
|
(reverse (if found reversed
|
|
(cons (cons field value) reversed))))
|
|
(let ((entry (car fields)))
|
|
(if (eq? (car entry) field)
|
|
(loop (cdr fields) (cons (cons field value) reversed) #t)
|
|
(loop (cdr fields) (cons entry reversed) found))))))))
|
|
|
|
(provide 'dat:record)
|