-
Notifications
You must be signed in to change notification settings - Fork 0
/
encode.clj
89 lines (65 loc) · 1.59 KB
/
encode.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
(ns dynamodb.encode
"
https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_AttributeValue.html
"
(:require
[cheshire.core :as json]
[dynamodb.codec :as codec]
[dynamodb.util :as util]))
(defprotocol IEncode
(-encode [this]))
(defn encode-bytes [^bytes bytea]
(-> bytea
(codec/b64-encode)
(codec/bytes->str "utf-8")))
(extend-protocol IEncode
(Class/forName "[B")
(-encode [^bytes this]
{:B (encode-bytes this)})
clojure.lang.Keyword
(-encode [this]
(-> this str (subs 1) -encode))
Object
(-encode [this]
(-encode (.toString this)))
Boolean
(-encode [this]
{:BOOL this})
String
(-encode [this]
{:S this})
Number
(-encode [this]
{:N (json/generate-string this)})
nil
(-encode [_this]
{:NULL true})
clojure.lang.IPersistentVector
(-encode [this]
{:L (mapv -encode this)})
clojure.lang.IPersistentList
(-encode [this]
{:L (mapv -encode this)})
clojure.lang.IPersistentSet
(-encode [this]
(let [item (first this)]
(cond
(number? item)
{:NS (set (map json/generate-string this))}
(string? item)
{:SS this}
(bytes? item)
{:BS (mapv encode-bytes this)}
:else
(throw
(ex-info
"Cannot encode a set: either it's empty or its item is of an improper type."
{:set this
:item item})))))
clojure.lang.IPersistentMap
(-encode [this]
{:M (util/update-vals this -encode)}))
(defn encode [value]
(-encode value))
(defn encode-attrs [mapping]
(util/update-vals mapping -encode))