Skip to content

Commit 6385ef2

Browse files
committed
Implemented the transformers. Improved the implementation of describe for the :condition-model properties.
1 parent e81abf5 commit 6385ef2

File tree

6 files changed

+71
-9
lines changed

6 files changed

+71
-9
lines changed

src/minimallist/core.cljc

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
:and :or
1717
:set-of :map-of :map :sequence-of :sequence
1818
:alt :cat :repeat
19+
:transform
1920
:let :ref])
2021

2122
;; There are 2 kinds of predicates:
@@ -131,6 +132,9 @@
131132
(-valid? context (:count-model model) (count data)))
132133
(implies (contains? model :condition-model)
133134
(-valid? context (:condition-model model) data)))
135+
:transform (and (implies (contains? model :condition-model)
136+
(-valid? context (:condition-model model) data))
137+
(-valid? context (:child-model model) ((:destruct model) data)))
134138
:let (-valid? (into context (:bindings model)) (:body model) data)
135139
:ref (-valid? context (get context (:key model)) data)))
136140

@@ -219,7 +223,7 @@
219223
(implies (contains? model :count-model)
220224
(:valid? (-describe context (:count-model model) (count data))))
221225
(implies (contains? model :condition-model)
222-
(:valid? (-describe context (:condition-model model) data))))]
226+
(-valid? context (:condition-model model) data)))]
223227
{:valid? valid?
224228
:desc (into #{} (map :desc) entries)}))
225229
:map-of (if (map? data)
@@ -239,7 +243,7 @@
239243
(implies (contains? model :values)
240244
(every? :valid? (vals entries)))
241245
(implies (contains? model :condition-model)
242-
(:valid? (-describe context (:condition-model model) data))))]
246+
(-valid? context (:condition-model model) data)))]
243247
{:valid? valid?
244248
:desc (into {} (map (fn [[k v]] [(:desc k) (:desc v)])) entries)})
245249
{:valid? false})
@@ -254,7 +258,7 @@
254258
valid? (and (implies (contains? model :entries)
255259
(every? :valid? (vals entries)))
256260
(implies (contains? model :condition-model)
257-
(:valid? (-describe context (:condition-model model) data))))]
261+
(-valid? context (:condition-model model) data)))]
258262
{:valid? valid?
259263
:desc (into {} (map (fn [[k v]] [k (:desc v)])) entries)})
260264
{:valid? false})
@@ -279,7 +283,7 @@
279283
(implies (contains? model :elements-model)
280284
(every? :valid? entries))
281285
(implies (contains? model :condition-model)
282-
(:valid? (-describe context (:condition-model model) data))))]
286+
(-valid? context (:condition-model model) data)))]
283287
{:valid? valid?
284288
:desc (mapv :desc entries)})
285289
{:valid? false})
@@ -305,9 +309,17 @@
305309
(if (seq seq-descriptions)
306310
{:desc (:desc (first seq-descriptions))
307311
:valid? (implies (contains? model :condition-model)
308-
(:valid? (-describe context (:condition-model model) data)))}
312+
(-valid? context (:condition-model model) data))}
309313
{:valid? false}))
310314
{:valid? false})
315+
:transform (if (implies (contains? model :condition-model)
316+
(-valid? context (:condition-model model) data))
317+
(let [description (-describe context (:child-model model) ((:destruct model) data))]
318+
(if (:valid? description)
319+
{:valid? true
320+
:desc ((:construct model) (:desc description))}
321+
{:valid? false}))
322+
{:valid? false})
311323
:let (-describe (into context (:bindings model)) (:body model) data)
312324
:ref (-describe context (get context (:key model)) data)))
313325

src/minimallist/generator.cljc

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,8 @@
9999
walk (conj path :entries index :model)))
100100
[stack walked-bindings]
101101
(map-indexed vector entries)))))
102+
:transform (-> [[stack walked-bindings] model]
103+
(reduce-update :child-model walk (conj path :child-model)))
102104
:let (let [[[stack' walked-bindings'] walked-body] (walk [(conj stack {:bindings (:bindings model)
103105
:path (conj path :bindings)})
104106
walked-bindings]
@@ -169,6 +171,7 @@
169171
(map (comp ::leaf-distance :model)))]
170172
(when (every? some? distances)
171173
(inc (reduce max 0 distances))))
174+
:transform (some-> (-> model :child-model ::leaf-distance) inc)
172175
:let (some-> (-> model :body ::leaf-distance) inc)
173176
:ref (let [key (:key model)
174177
index (find-stack-index stack key)
@@ -221,6 +224,7 @@
221224
(map (comp ::min-cost :model)))
222225
content-cost (when (every? some? vals) (reduce + vals))]
223226
(some-> content-cost (+ container-cost)))
227+
:transform (some-> (::min-cost (:child-model model)) inc)
224228
:let (::min-cost (:body model))
225229
:ref (let [key (:key model)
226230
index (find-stack-index stack key)]
@@ -491,6 +495,10 @@
491495
inside-list? (gen/fmap (partial apply list))))))
492496
(contains? model :condition-model) (gen/such-that (partial m/valid? context (:condition-model model))))
493497

498+
:transform (cond->> (generator context (:child-model model) budget)
499+
(contains? model :construct) (gen/fmap (:construct model))
500+
(contains? model :condition-model) (gen/such-that (partial m/valid? context (:condition-model model))))
501+
494502
:let (generator (merge context (:bindings model)) (:body model) budget)
495503

496504
:ref (generator context (get context (:key model)) budget))))

src/minimallist/helper.cljc

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,17 @@
206206
[model]
207207
(repeat 1 ##Inf model))
208208

209+
(defn transform
210+
"Transformation of a data matching the model.
211+
`destruct` is used during validation and parsing, and
212+
`construct` is used during parsing and generation."
213+
([model destruct]
214+
{:type :transform
215+
:child-model model
216+
:destruct destruct})
217+
([model destruct construct]
218+
(assoc (transform model destruct) :construct construct)))
219+
209220
(defn let
210221
"Model with local model definitions."
211222
[bindings body]

src/minimallist/minimap.cljc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,11 @@
6060
[:inlined (h/fn boolean?)]
6161
[:condition-model (h/ref 'model)])
6262
(h/with-condition (h/fn #(<= (:min %) (:max %)))))]
63+
[:transform (-> (h/map [:type (h/val :transform)]
64+
[:child-model (h/ref 'model)]
65+
[:destruct (h/fn fn?)])
66+
(h/with-optional-entries [:construct (h/fn fn?)]
67+
[:condition-model (h/ref 'model)]))]
6368
[:let (h/map [:type (h/val :let)]
6469
[:bindings (h/map-of (h/fn any?)
6570
(h/ref 'model))]

test/minimallist/core_test.cljc

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
(ns minimallist.core-test
22
(:require [clojure.test :refer [deftest testing is are]]
33
[minimallist.core :refer [valid? explain describe undescribe] :as m]
4-
[minimallist.helper :as h]
5-
[minimallist.util :as util]))
4+
[minimallist.helper :as h]))
65

76
(comment
87
(#'m/sequence-descriptions {}
@@ -226,6 +225,14 @@
226225
['div]
227226
[:div {:a 1} "hei" [:p {} {} "bonjour"]]]
228227

228+
;; transform
229+
(-> (h/transform (h/sequence-of (h/enum #{"A" "T" "G" "C"}))
230+
#(mapv str (seq %))
231+
#(apply str %))
232+
(h/with-condition (h/fn string?)))
233+
["" "A" "CGATCAT"]
234+
[:foobar "CGAUCAU" "AOEU"]
235+
229236
;; let / ref - with recursion within a sequence
230237
(h/let ['foo (h/cat (h/fn int?)
231238
(h/? (h/ref 'foo))
@@ -444,6 +451,18 @@
444451
[1 "a" 2 "b"] :invalid
445452
[1 "a" 2 "b" 3 "c"] :invalid]
446453

454+
;; transform
455+
(-> (h/transform (h/sequence-of (h/enum #{"A" "T" "G" "C"}))
456+
#(mapv str (seq %))
457+
#(apply str %))
458+
(h/with-condition (h/fn string?)))
459+
["" ""
460+
"A" "A"
461+
"CGATCAT" "CGATCAT"
462+
:foobar :invalid
463+
"CGAUCAU" :invalid
464+
"AOEU" :invalid]
465+
447466
;; let / ref
448467
(h/let ['pos-even? (h/and (h/fn pos-int?)
449468
(h/fn even?))]
@@ -456,5 +475,5 @@
456475

457476
(doseq [[model data-description-pairs] (partition 2 test-data)]
458477
(doseq [[data description] (partition 2 data-description-pairs)]
459-
(is (= [data (describe model data)]
460-
[data description]))))))
478+
(is (= [data description]
479+
[data (describe model data)]))))))

test/minimallist/generator_test.cljc

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -427,6 +427,13 @@
427427
(is (every? (partial valid? model)
428428
(tcg/sample (gen model)))))
429429

430+
(let [model (-> (h/transform (h/sequence-of (h/enum #{"A" "T" "G" "C"}))
431+
#(mapv str (seq %))
432+
#(apply str %))
433+
(h/with-condition (h/fn string?)))]
434+
(is (every? (partial valid? model)
435+
(tcg/sample (gen model)))))
436+
430437
(let [model (h/let ['int? fn-int?
431438
'string? fn-string?
432439
'int-string? (h/cat (h/ref 'int?) (h/ref 'string?))]

0 commit comments

Comments
 (0)