forked from jimmythompson/halboy
-
Notifications
You must be signed in to change notification settings - Fork 2
/
json.clj
73 lines (61 loc) · 1.85 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
(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]
(or (dissoc m :_links :_embedded) {}))
(defn- map->embedded-resource [m]
(if (map? m)
(map->resource m)
(map map->embedded-resource m)))
(defn- extract-embedded [body]
(transform-values (:_embedded body {}) map->embedded-resource))
(defn- links->map [resource]
(let [links (:links resource)]
(when (seq 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 (transform-values (:embedded resource) embedded-resource->map)]
(when (seq 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]
(json/generate-string (resource->map resource)))