Files
dat-thang/scheme/dat-record.scm
T
divorce b735900f2e 0.0.002
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>
2026-10-19 00:17:02 -04:00

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)