-
-
Notifications
You must be signed in to change notification settings - Fork 24
/
json-util.rkt
52 lines (46 loc) · 1.88 KB
/
json-util.rkt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#lang racket/base
(require (for-syntax racket/base
syntax/parse)
racket/match
syntax/parse)
(define-syntax (define-json-expander stx)
(syntax-parse stx
[(_ name:id [key:id ctc:expr] ...+)
(with-syntax ([(key_ ...) (generate-temporaries #'(key ...))]
[(keyword ...)
(for/list ([k (syntax->datum #'(key ...))])
(string->keyword (symbol->string k)))]
[~?-id (quote-syntax ~?)])
(syntax/loc stx
(define-match-expander name
(λ (stx)
(syntax-parse stx
[(_ (~optional (~seq keyword key_)) ...)
(quasisyntax/loc stx (hash-table (~?-id ['key (? ctc key_)]) ...))]))
(λ (stx)
(syntax-parse stx
[(_ (~optional (~seq keyword key_)) ...)
(syntax/loc stx
(make-hasheq (list (cons 'key key_) ...)))])))))]))
(define (jsexpr-has-key? jsexpr keys)
(cond [(null? keys) #t]
[else (and (hash-has-key? jsexpr (car keys))
(jsexpr-has-key? (hash-ref jsexpr (car keys)) (cdr keys)))]))
(define (jsexpr-ref jsexpr keys)
(cond [(null? keys) jsexpr]
[else (jsexpr-ref (hash-ref jsexpr (car keys)) (cdr keys))]))
(define (jsexpr-set jsexpr keys v)
(cond [(null? keys) jsexpr]
[(null? (cdr keys)) (hash-set jsexpr (car keys) v)]
[else (hash-set jsexpr (car keys)
(jsexpr-set (hash-ref jsexpr (car keys)) (cdr keys) v))]))
(define (jsexpr-remove jsexpr keys)
(cond [(null? keys) jsexpr]
[(null? (cdr keys)) (hash-remove jsexpr (car keys))]
[else (hash-set jsexpr (car keys)
(jsexpr-remove (hash-ref jsexpr (car keys)) (cdr keys)))]))
(provide define-json-expander
jsexpr-has-key?
jsexpr-ref
jsexpr-set
jsexpr-remove)