-
Notifications
You must be signed in to change notification settings - Fork 1
/
json.cljc
64 lines (52 loc) · 2.16 KB
/
json.cljc
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
(ns com.yetanalytics.persephone.utils.json
(:require [clojure.spec.alpha :as s]
[xapi-schema.spec :as xs]
[com.yetanalytics.pathetic :as pathetic]
[com.yetanalytics.pan.objects.profile :as pan-profile]
[com.yetanalytics.pan.utils.json :refer [convert-json]]
#?(:clj [clojure.data.json :as json])))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; JSON to EDN
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defn- json->edn
"Convert a JSON data structure to EDN. By default, keys will
remain strings. If `keywordize?` is true then all keys are
turned into keywords, with all instances `@` replaced with
`_` (this is not recommended for IRI keys)."
[json-str keywordize?]
(if keywordize?
(convert-json json-str "_")
#?(:clj (json/read-str json-str)
:cljs (js->clj (.parse js/JSON json-str)))))
(s/fdef coerce-profile
:args string?
:ret ::pan-profile/profile)
(defn coerce-profile
"Coerce a Profile JSON string into EDN, keywordizing keys and converting
\"@context\" into `:_context`."
[profile-json]
(json->edn profile-json true))
(s/fdef coerce-statement
:args string?
:ret ::xs/statement)
(defn coerce-statement
"Coerce a Statement JSON string into EDN, stringifying keys."
[statement-json]
(json->edn statement-json false))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; JSONPath operations
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Parsing is an expensive operation, and many JSONPath strings are repeated in
;; a given Profile, so we call `memoize` to cache already parsed paths.
(def parse-jsonpath
"Parse a single arg `path-str` and return a vector of parsed
JSONPaths."
(memoize pathetic/parse-paths))
;; Wrapper for pathetic/get-values*
;; We don't use `memoize` here because `json` Statements are usually different.
(def opts-map {:return-missing? true})
(defn get-jsonpath-values
"Given `json` and parsed JSONPaths `paths`, return a vector of JSON
valuess."
[json paths]
(pathetic/get-values* json paths opts-map))