Commit3996ad74Recorded25 Feb 2026Repositorysigil-json
Add procedure specs to (sigil json) and update docstrings
Message
6 exports: json-read, json-write, json-encode, json-decode, json-get-in, json-null?. Updates docstring examples to use dict syntax instead of legacy alist syntax.
Changed
src/sigil/json.sgl | 29 +++++++++++++++++------------
1 file changed, 17 insertions(+), 12 deletions(-)Diff
src/sigil/json.sglmodified
@@ -42,7 +42,7 @@
42
;;; ;; Write JSON to a port (streaming) 43
;;; (call-with-output-file "data.json" 44
;;; (lambda (port)−45
;;; (json-write '((name . "Alice")) port)))+45
;;; (json-write #{ name: "Alice" } port))) 46
;;; 47
;;; ;; Read JSON from a port 48
;;; (call-with-input-file "data.json" json-read)@@ -51,10 +51,10 @@
51
;;; ## Pretty Printing 52
;;; 53
;;; ```scheme−54
;;; (json-encode '((name . "Alice") (age . 30)) indent: #t)+54
;;; (json-encode #{ name: "Alice" age: 30 } indent: #t) 55
;;; ; => "{\n \"name\": \"Alice\",\n \"age\": 30\n}" 56
;;;−57
;;; (json-encode '((a . 1)) indent: 4) ; 4-space indentation+57
;;; (json-encode #{ a: 1 } indent: 4) ; 4-space indentation 58
;;; ``` 59
;;; 60
;;; ## Path Access@@ -111,13 +111,13 @@
111
;;; 112
;;; ```scheme 113
;;; ;; Write to stdout−114
;;; (json-write '((name . "Alice")) (current-output-port))+114
;;; (json-write #{ name: "Alice" } (current-output-port)) 115
;;; ; outputs: {"name":"Alice"} 116
;;; 117
;;; ;; Write to a file 118
;;; (call-with-output-file "data.json" 119
;;; (lambda (port)−120
;;; (json-write '((name . "Alice") (age . 30)) port indent: #t)))+120
;;; (json-write #{ name: "Alice" age: 30 } port indent: #t))) 121
;;; 122
;;; ;; Stream to a socket 123
;;; (json-write response-data socket-port)@@ -126,6 +126,7 @@
126
;;; (json-write data port indent: 4) 127
;;; ``` 128
(%set-docstring! json-write)+129
(%set-spec! json-write '(any? port? (indent: (any-of boolean? integer?)) -> void?)) 130
131
;; Internal: write any JSON value 132
;; indent-size is #f for compact, or a number for pretty-printing@@ -344,6 +345,7 @@
345
;;; (call-with-input-string "42" json-read) ; => 42 346
;;; ``` 347
(define (json-read port)+348
(: port? -> any?) 349
(skip-whitespace port) 350
(let ((c (peek-char port))) 351
(cond@@ -551,12 +553,12 @@
553
;;; - `indent: #f` - compact output (default) 554
;;; 555
;;; ```scheme−554
;;; ;; Encode objects (alists become JSON objects)−555
;;; (json-encode '((name . "Alice") (age . 30)))+556
;;; ;; Encode dicts as JSON objects+557
;;; (json-encode #{ name: "Alice" age: 30 }) 558
;;; ; => "{\"name\":\"Alice\",\"age\":30}" 559
;;;−558
;;; ;; Encode arrays (lists become JSON arrays)−559
;;; (json-encode '(1 2 3))+560
;;; ;; Encode arrays+561
;;; (json-encode #[1 2 3]) 562
;;; ; => "[1,2,3]" 563
;;; 564
;;; ;; Encode primitives@@ -566,13 +568,13 @@
568
;;; (json-encode 'null) ; => "null" 569
;;; 570
;;; ;; Pretty-print with 2-space indentation−569
;;; (json-encode '((a . 1) (b . (1 2 3))) indent: #t)−570
;;; ; => "{\n \"a\": 1,\n \"b\": [\n 1,\n 2,\n 3\n ]\n}"+571
;;; (json-encode #{ a: 1 b: #[1 2 3] } indent: #t) 572
;;; 573
;;; ;; Custom indentation (4 spaces)−573
;;; (json-encode '((x . 1)) indent: 4)+574
;;; (json-encode #{ x: 1 } indent: 4) 575
;;; ``` 576
(%set-docstring! json-encode)+577
(%set-spec! json-encode '(any? (indent: (any-of boolean? integer?)) -> string?)) 578
579
;;; Decode a JSON string into a Scheme value. 580
;;;@@ -607,6 +609,7 @@
609
;;; ; => ((x . 1)) 610
;;; ``` 611
(define (json-decode str)+612
(: string? -> any?) 613
(call-with-input-string str json-read)) 614
615
;; ========== Path Access ==========@@ -637,6 +640,7 @@
640
;;; ; => #f 641
;;; ``` 642
(define (json-get-in value path . default)+643
(: any? list? any? ... -> any?) 644
(let ((def (if (null? default) #f (car default)))) 645
(let loop ((v value) (p path)) 646
(if (null? p)@@ -685,6 +689,7 @@
689
;;; (json-null? (json-decode "false")) ; => #f 690
;;; ``` 691
(define (json-null? value)+692
(: any? -> boolean?) 693
(eq? value 'null)) 694
695
;; Check if list is an alist (list of pairs with symbol/string keys)