-
Notifications
You must be signed in to change notification settings - Fork 17
/
json.clj
78 lines (65 loc) · 1.95 KB
/
json.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
(ns halboy.json
(:require
[clojure.walk :refer [keywordize-keys]]
[halboy.data :refer [transform-values]]
[halboy.resource :as hal]
[cheshire.core :as json])
(:import (com.fasterxml.jackson.core JsonParseException)))
(declare map->resource resource->map)
(defn- extract-links [m]
(:_links m {}))
(defn- extract-properties [m]
(-> (dissoc m :_links :_embedded)
(or {})))
(defn- map->embedded-resource [m]
(if (map? m)
(map->resource m)
(map map->embedded-resource m)))
(defn- extract-embedded [body]
(-> (:_embedded body {})
(transform-values map->embedded-resource)))
(defn- links->map [resource]
(let [links (:links resource)]
(when (not (empty? links))
{:_links links})))
(defn- embedded-resource->map [resource]
(if (map? resource)
(resource->map resource)
(map embedded-resource->map resource)))
(defn- embedded->map [resource]
(let [resources (-> (:embedded resource)
(transform-values embedded-resource->map))]
(when (not (empty? resources))
{:_embedded resources})))
(defn map->resource
"Parses a map representing a HAL+JSON response into a
resource"
[m]
(-> (hal/new-resource)
(hal/add-links (extract-links m))
(hal/add-resources (extract-embedded m))
(hal/add-properties (extract-properties m))))
(defn json->resource
"Parses a HAL+JSON string into a resource"
[s]
(try
(-> (json/parse-string s)
keywordize-keys
map->resource)
(catch JsonParseException e
(throw (ex-info "Failed to parse json"
{:exception e
:string s})))))
(defn resource->map
"Transforms a resource into a map representing a HAL+JSON
response"
[resource]
(merge
(links->map resource)
(embedded->map resource)
(:properties resource)))
(defn resource->json
"Transforms a resource into a HAL+JSON string"
[resource]
(-> (resource->map resource)
json/generate-string))