-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathtransducers.clj
102 lines (91 loc) · 3.38 KB
/
transducers.clj
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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
(ns jq.transducers
(:require [jq.api :as api]
[jq.api.api-impl :as impl])
(:import (com.fasterxml.jackson.databind ObjectMapper SerializationFeature)
(java.io Reader)
(java.util Iterator)))
(defn ->JsonNode
"Returns a transducer that given a Java object maps it to a JsonNode.
Accepts an optional Jackson ObjectMapper."
([] (map impl/->JsonNode))
([^ObjectMapper mapper]
(map (partial impl/->JsonNode mapper))))
(defn JsonNode->value
"Returns a transducer that give a JsonNode maps it to a Java Object.
Accepts an optional Jackson ObjectMapper."
([] (map impl/JsonNode->clj))
([^ObjectMapper mapper]
(map (partial impl/JsonNode->clj mapper))))
(defn parse
"Returns a transducer that given a JSON String parses it into a JsonNode.
Accepts an optional Jackson ObjectMapper."
([] (map impl/string->json-node))
([^ObjectMapper mapper]
(map (partial impl/string->json-node mapper))))
(defn rdr->json-nodes
"Returns a transducer that given a java.io.Reader parses it into a stream of JsonNode.
Accepts an optional Jackson ObjectMapper."
([] (rdr->json-nodes impl/mapper))
([^ObjectMapper mapper]
(fn [rf]
(fn transducer
([] (rf))
([acc] (rf acc))
([acc ^Reader rdr]
(loop [^Iterator iter (impl/rdr->json-node-iter mapper rdr)]
(if (.hasNext iter)
(do
(rf acc (.next iter))
(recur iter))
acc)))))))
(comment
(sequence (rdr->json-nodes) [(java.io.StringReader. "\"hello\" \"world\"")]))
(defn serialize
"Returns a transducer that given a JsonNode serializes it to a String.
Accepts an optional Jackson ObjectMapper."
([] (map impl/json-node->string))
([^ObjectMapper mapper]
(map (partial impl/json-node->string mapper))))
;; Pretty printer serializer
(defn pretty-print
"Same as the `serializer` but the output string is indented.
ObjectMapper is copied to prevent side effects in case mapper is shared."
([] (pretty-print impl/mapper))
([^ObjectMapper mapper]
(map (partial impl/json-node->string
(.enable (.copy mapper) SerializationFeature/INDENT_OUTPUT)))))
(defn execute
"Returns a transducer that accepts JsonNode on which
the expression will be applied.
Optional opts are supported that are passed for the `jq.api/stream-processor`.
Specific opts for the transducer:
:cat - whether to catenate output, default true"
([^String expression] (execute expression {}))
([^String expression opts]
(if (false? (:cat opts))
(map (api/stream-processor expression opts))
(impl/fast-transducer expression opts))))
(defn process
"Returns a convenience transducer that:
- maps a Java Object to a JsonNode;
- maps a JQ expression on the JsonNode;
- catenates the output;
- maps a JsonNode to a JavaObject.
Accept opts that will be passed to the `jq.api/stream-processor`
Accepts a Jackson ObjectMapper that will be used for both"
([^String expression] (process expression {}))
([^String expression opts] (process expression opts impl/mapper))
([^String expression opts ^ObjectMapper mapper]
(comp
(->JsonNode mapper)
(execute expression (assoc opts :cat true))
(JsonNode->value mapper))))
(comment
; Duplicates input
(into []
(comp
(->JsonNode)
(execute "(. , .)")
(JsonNode->value))
[1 2 3])
(into [] (process "(. , .)") [1 2 3]))