-
Notifications
You must be signed in to change notification settings - Fork 1
/
transformations.cljc
66 lines (55 loc) · 1.83 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
59
60
61
62
63
64
65
66
(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 args]
(cond->> model
:always (map #(transform config % args))
(set? model) (set)
(vector? model) (vec)
(map? model) (into {})))
(defmethod ^:private transform :map
[config model args]
(let [[key-config val-config] (first config)]
(some->> model
(map (fn [[k v]] [(transform key-config k args) (transform val-config v args)]))
(into {}))))
(defmethod ^:private transform :tuple
[config model args]
(let [i (if (:com.ben-allred.formation.core/limit-to (meta config))
(count config)
(max (count config) (count model)))]
(some->> (range i)
(map (fn [i] (transform (nth config i nil) (nth model i nil) args)))
(vec))))
(defmethod ^:private transform :record
[config model args]
(when model)
(-> model
(cond->
(:com.ben-allred.formation.core/limit-to (meta config))
(select-keys (keys config)))
(->>
(map (fn [[k v]] [k (transform (get config k) v args)]))
(into {}))))
(defmethod ^:private transform :combine
[[config & configs] model args]
(loop [[cfg :as more] configs f #(transform config % args)]
(if (empty? more)
(transform f model args)
(recur (rest more) (comp #(transform cfg % args) f)))))
(defmethod ^:private transform :fn
[config model args]
(apply config model args))
(defmethod ^:private transform :ifn
[config model _]
(config model))
(defmethod ^:private transform :default
[_ model _]
model)
(defn transformer [config]
(fn [model & args]
(transform config model args)))