/
core.clj
108 lines (85 loc) · 3.85 KB
/
core.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
103
104
105
106
107
108
(ns atmos-kernel.serializer.core
(:require [atmos-kernel.serializer.coercions :refer :all]
[atmos-kernel.core :refer [in?]])
(:import (java.util List Map)))
(defrecord SerializerField [value response-name-value])
(defrecord DeSerializerField [value class options])
(defprotocol FieldValueProtocol
(field-value [field]))
(defprotocol FieldSerializationProtocol
(response-name [field]))
(defprotocol FieldDeSerializationProtocol
(has-option? [this option])
(parse [this]))
(defprotocol EntitySerializationProtocol
(serialize [data serializer-fn])
(de-serialize [data de-serialize-fn]))
(extend-protocol EntitySerializationProtocol
nil
(serialize [_ _] nil)
(de-serialize [_ _] nil)
Map
(serialize [data serialize-fn] (let [data-serialized (if-not (nil? serialize-fn)
(serialize-fn data)
data)
data-structure (keys data-serialized)
data (map (fn [field]
(let [data (field data-serialized)]
(vector (response-name data)
(field-value data))))
data-structure)]
(into {} data)))
(de-serialize [data de-serialize-fn] (let [data-de-serialized (if-not (nil? de-serialize-fn)
(de-serialize-fn data)
data)
data-structure (keys data-de-serialized)
data (map (fn [field]
(let [data (field data-de-serialized)]
(vector field (if (record? data)
(parse data)
(de-serialize data nil)))))
data-structure)]
(into {} data)))
List
(serialize [data serialize-fn] (map (fn [record]
(serialize record serialize-fn)) data))
(de-serialize [data de-serialize-fn] (map (fn [record]
(de-serialize record de-serialize-fn)) data)))
(extend-protocol FieldValueProtocol
Map
(field-value [data] data)
SerializerField
(field-value [field] (:value field))
DeSerializerField
(field-value [field] (:value field)))
(extend-protocol FieldSerializationProtocol
Map
(response-name [field] (:response-name-value field))
SerializerField
(response-name [field] (:response-name-value field)))
(extend-protocol FieldDeSerializationProtocol
DeSerializerField
(parse [field] (parse-data (:value field) (:class field)))
(has-option? [field option] (in? (:options field) option))
nil
(parse [_] nil))
(defn serializer-field
[value response-name]
(->SerializerField value (keyword response-name)))
(defn de-serializer-field
([value class options]
(->DeSerializerField value class options))
([value class]
(de-serializer-field value class [:required]))
([value]
(de-serializer-field value :string)))
(defn make-fields
[record make-field-fn fields]
(apply record (map
(fn
[field]
(let [property (first field)
property-metadata (second field)]
(make-field-fn property property-metadata)))
fields)))
(defn mapping [record] (into {} record))