From 2ea47db5c6e6957fbf669f3457fb2efb3f3d0aa9 Mon Sep 17 00:00:00 2001 From: Artyom Bologov Date: Fri, 2 Feb 2024 18:44:23 +0400 Subject: [PATCH 1/3] functions(jget*): Automatically decode from pathnames/streams. This way, it's easier for quick-and-dirty json indexing on files and streams, without the need to parse them first. String-parsing is not supported due to it being ambiguous: - Is it a string to be parsed and then acted upon? - Or is it a string that is erroneously indexed with wrong indices? Closes #15. --- functions.lisp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/functions.lisp b/functions.lisp index e252317..c68d378 100644 --- a/functions.lisp +++ b/functions.lisp @@ -112,6 +112,10 @@ CHAR is left unread on STREAM after returning." (cerror "Return nothing" 'non-indexable :value object) (values nil nil)) + (:method (key (object pathname)) + (jget* key (decode-from-file object))) + (:method (key (object stream)) + (jget* key (decode-from-stream object))) (:method ((key string) (object string)) (declare (ignore key)) (cerror "Return nothing" From 3dac8f7c1c72a724ddffd3bdbc977b919d9c29d8 Mon Sep 17 00:00:00 2001 From: Artyom Bologov Date: Fri, 2 Feb 2024 23:38:38 +0400 Subject: [PATCH 2/3] tests: Add inline file/stream decoding test. --- tests/tests.lisp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/tests/tests.lisp b/tests/tests.lisp index aeb15ac..df71f48 100644 --- a/tests/tests.lisp +++ b/tests/tests.lisp @@ -235,3 +235,15 @@ ;; (assert-no-key #(("data" ("parents" _)))) ;; (assert-no-key #(("data" ("parents" ("nested" :true))))) ))) + +(define-test inline-decode-file/stream () + (let* ((baker-file (asdf:system-relative-pathname :njson "tests/baker.json")) + (baker-stream (open baker-file)) + (baker-decoded (decode baker-file))) + (assert-equal "Henry Baker: Meta-circular semantics for Common Lisp special forms" + (jget #(0 "data" "children" 0 "data" "title") baker-decoded)) + (assert-equal "Henry Baker: Meta-circular semantics for Common Lisp special forms" + (jget #(0 "data" "children" 0 "data" "title") baker-file)) + (assert-equal "Henry Baker: Meta-circular semantics for Common Lisp special forms" + (jget #(0 "data" "children" 0 "data" "title") baker-stream)) + (close baker-stream))) From 3187032da23d67c3c13d3875f2567391d710c4e3 Mon Sep 17 00:00:00 2001 From: Artyom Bologov Date: Fri, 2 Feb 2024 23:40:42 +0400 Subject: [PATCH 3/3] Document inline file/index behavior. --- README.org | 4 ++++ functions.lisp | 7 +++++++ 2 files changed, 11 insertions(+) diff --git a/README.org b/README.org index 3ef6594..2d90e78 100644 --- a/README.org +++ b/README.org @@ -138,6 +138,10 @@ entry under key is found (like in ~gethash~). (njson:jget #p"/second-key/0" data) ;; => 1, T + ;; Can decode and index files as an alias for `njson:decode'. + (njson:jget #(0 "kind") #p"tests/baker.json") + ;; "Listing" + ;; Modify the element in place: (setf (njson:jget #p"/second-key/0" data) 3) ;; Another indexing syntax, for no particular reason: diff --git a/functions.lisp b/functions.lisp index c68d378..044870e 100644 --- a/functions.lisp +++ b/functions.lisp @@ -141,6 +141,13 @@ KEY-OR-INDEX can be - a sequence of integers and strings (to index the nested structures). - an empty sequence/pathname (to match the whole object). +OBJECT can be +- A hash table, indexed by strings +- An array, indexed by integers +- A stream, which is `decode'd and then indexed +- A pathname, which is `decode'd and then indexed +- Anything else, considered an error (see below) + Return two values: the value under KEY-OR-INDEX and whether this value was found.