-
Notifications
You must be signed in to change notification settings - Fork 0
/
model.cljc
51 lines (50 loc) · 3.27 KB
/
model.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
(ns ^:no-doc diffuse.model
(:require [clojure.set :as set]
[minimallist.helper :as h]))
;; A model of a diff, only used for validation.
(def diff-model
(h/let ['key (h/fn any?)
'value (h/fn any?)
'index (-> (h/fn int?)
(h/with-condition
(h/fn #(>= % 0))))
'size (h/fn pos-int?)
'diff (h/alt [:nil (h/val nil)]
[:missing (h/map [:type (h/val :missing)])]
[:value (h/map [:type (h/val :value)]
[:value (h/ref 'value)])]
[:set (-> (h/map
[:type (h/val :set)])
(h/with-optional-entries
[:disj (h/set-of (h/ref 'value))]
[:conj (h/set-of (h/ref 'value))])
(h/with-condition
(h/fn (fn [diff]
(let [{disj-set :disj, conj-set :conj} diff]
(and (or (seq disj-set) (seq conj-set))
(empty? (set/intersection disj-set conj-set))))))))]
[:map (h/map
[:type (h/val :map)]
[:key-op (-> (h/map-of (h/ref 'key)
(h/alt [:assoc (h/vector (h/val :assoc)
(h/ref 'value))]
[:update (h/vector (h/val :update)
(h/ref 'diff))]
[:dissoc (h/vector (h/val :dissoc))]))
(h/with-condition
(h/fn (fn [key-op]
(pos? (count key-op))))))])]
[:vector (h/map
[:type (h/val :vector)]
[:index-op (-> (h/vector-of (h/alt [:no-op (h/vector (h/val :no-op)
(h/ref 'size))]
[:update (h/vector (h/val :update)
(h/in-vector (h/+ (h/ref 'diff))))]
[:remove (h/vector (h/val :remove)
(h/ref 'size))]
[:insert (h/vector (h/val :insert)
(h/in-vector (h/+ (h/ref 'value))))]))
(h/with-condition
(h/fn (fn [index-op]
(pos? (count index-op))))))])])]
(h/ref 'diff)))