Skip to content

Commit

Permalink
Merge pull request #973 from frenchy64/merge-demo
Browse files Browse the repository at this point in the history
Document :or vs :union vs :merge
  • Loading branch information
ikitommi authored Nov 22, 2023
2 parents 4c788a6 + d63ce56 commit 266579e
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 0 deletions.
56 changes: 56 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1486,6 +1486,62 @@ Merged
; => true
```

`:union` is similar to `:or`, except `:union` combines map schemas in different disjuncts with `:or`.
For example, `UnionMaps` is equivalent to `[:map [:x [:or :int :string]] [:y [:or :int :string]]]`.

```clojure
(def OrMaps
(m/schema
[:or
[:map [:x :int] [:x :string]]
[:map [:x :string] [:x :int]]]
{:registry registry}))

(def UnionMaps
(m/schema
[:union
[:map [:x :int] [:x :string]]
[:map [:x :string] [:x :int]]]
{:registry registry}))

(m/validate OrMaps {:x "kikka" :y "kikka"})
; => false

(m/validate UnionMaps {:x "kikka" :y "kikka"})
; => true
```

`:merge` and `:union` differ on schemas with common keys. `:merge` chooses the right-most
schema of common keys, and `:union` combines them with `:or`.
For example, `MergedCommon` is equivalent to `[:map [:x :int]]`, and `UnionCommon`
is equivalent to `[:map [:x [:or :string :int]]]`.

```clojure
(def MergedCommon
(m/schema
[:merge
[:map [:x :string]]
[:map [:x :int]]]
{:registry registry}))

(def UnionCommon
(m/schema
[:union
[:map [:x :string]]
[:map [:x :int]]]
{:registry registry}))

(m/validate MergedCommon {:x "kikka"})
; => true
(m/validate MergedCommon {:x 1})
; => false
(m/validate UnionCommon {:x "kikka"})
; => true
(m/validate UnionCommon {:x 1})
; => true
```


## Persisting schemas

Writing and Reading schemas as [EDN](https://github.com/edn-format/edn), no `eval` needed.
Expand Down
26 changes: 26 additions & 0 deletions test/malli/util_test.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -822,6 +822,32 @@
(is (= {:x [:str "x"]} (m/parse s {:x "x"})))
(is (= {:x 1} (m/parse s {:x 1})))))

(testing "merge vs union"
(let [->s #(->> [%
[:map [:x :string]]
[:map [:x :int]]])
u (->s :union)
m (->s :merge)]
(is (m/validate u {:x 1}))
(is (m/validate u {:x "a"}))
(is (m/validate m {:x 1}))
(is (m/explain m {:x "a"}))))

(testing "union vs or"
(let [->s #(->> [%
[:map [:x :string] [:y :int]]
[:map [:x :int] [:y :string]]])
u (->s :union)
o (->s :or)]
(is (m/validate u {:x 1 :y 1}))
(is (m/validate u {:x 1 :y "a"}))
(is (m/validate u {:x "a" :y 1}))
(is (m/validate u {:x "a" :y "a"}))
(is (m/explain o {:x 1 :y 1}))
(is (m/validate o {:x 1 :y "a"}))
(is (m/validate o {:x "a" :y 1}))
(is (m/explain o {:x "a" :y "a"}))))

(testing "select-keys"
(let [s (->> [:select-keys
[:schema
Expand Down

0 comments on commit 266579e

Please sign in to comment.