-
Notifications
You must be signed in to change notification settings - Fork 1
/
transformations.cljc
58 lines (47 loc) · 1.5 KB
/
transformations.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
(ns com.ben-allred.formation.transformations
(:require
[com.ben-allred.formation.shared :as shared]))
(defn ^:private combine* [result-a result-b]
(comp result-b result-a))
(defmulti ^:private transform #'shared/dispatch)
(defmethod ^:private transform :coll
[[config] model]
(cond->> model
:always (map (partial transform config))
(set? model) (set)
(vector? model) (vec)
(map? model) (into {})))
(defmethod ^:private transform :map
[config model]
(let [[key-config val-config] (first config)]
(some->> model
(map (fn [[k v]] [(transform key-config k) (transform val-config v)]))
(into {}))))
(defmethod ^:private transform :tuple
[config model]
(let [i (max (count config) (count model))]
(some->> (range i)
(map (fn [i] (transform (nth config i nil) (nth model i nil))))
(vec))))
(defmethod ^:private transform :record
[config model]
(some->> model
(map (fn [[k v]] [k (transform (get config k) v)]))
(into {})))
(defmethod ^:private transform :combine
[[config & configs] model]
(loop [[cfg :as more] configs f (partial transform config)]
(if (empty? more)
(f model)
(recur (rest more) (comp (partial transform cfg) f)))))
(defmethod ^:private transform :fn
[config model]
(config model))
(defmethod ^:private transform :ifn
[config model]
(config model))
(defmethod ^:private transform :default
[_ model]
model)
(defn transformer [config]
(partial transform config))