From ead1d019cd4ab3a0f2c92b9b71ed93ddcc84865d Mon Sep 17 00:00:00 2001 From: Ambrose Bonnaire-Sergeant Date: Sat, 23 Mar 2024 09:29:16 -0500 Subject: [PATCH] Use :orn instead of :altn for map destructuring --- README.md | 4 ++-- src/malli/destructure.cljc | 6 +++--- test/malli/destructure_test.cljc | 18 +++++++++--------- test/malli/experimental_test.clj | 8 ++++++-- 4 files changed, 20 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 163967e81..eb63a5e1a 100644 --- a/README.md +++ b/README.md @@ -393,7 +393,7 @@ You can use `:sequential` to describe homogeneous sequential Clojure collections ;; => false ``` -Malli also supports sequence regexes (also called sequence expresions) like [Seqexp](https://github.com/cgrand/seqexp) and Spec. +Malli also supports sequence regexes (also called sequence expressions) like [Seqexp](https://github.com/cgrand/seqexp) and Spec. The supported operators are `:cat` & `:catn` for concatenation / sequencing ```clojure @@ -454,7 +454,7 @@ while `:cat` and `:alt` just use numeric indices for paths: ;; {:path [0 1 1], :in [3], :schema boolean?, :value 11})} ``` -As all these examples show, the sequence experssion (seqex) operators take any non-seqex child schema to +As all these examples show, the sequence expression (seqex) operators take any non-seqex child schema to mean a sequence of one element that matches that schema. To force that behaviour for a seqex child `:schema` can be used: diff --git a/src/malli/destructure.cljc b/src/malli/destructure.cljc index 400e1c2ee..1fa33c258 100644 --- a/src/malli/destructure.cljc +++ b/src/malli/destructure.cljc @@ -91,9 +91,9 @@ ->arg (fn [[k t]] [:cat [:= k] (if (and references (qualified-keyword? k)) k t)]) schema (cond-> [:map] closed-maps (conj {:closed true}) :always (into (map ->entry keys)))] (if (or rest sequential-maps) - [:altn [:map schema] [:args (-> (into [:alt] (map ->arg) keys) - (cond-> (not closed-maps) (conj [:cat [:not (into [:enum] (map first) keys)] :any])) - (cond->> :always (conj [:*]) (not rest) (conj [:schema])))]] + [:orn [:map schema] [:args (-> (into [:alt] (map ->arg) keys) + (cond-> (not closed-maps) (conj [:cat [:not (into [:enum] (map first) keys)] :any])) + (cond->> :always (conj [:*]) (not rest) (conj [:schema])))]] schema))) (defn -transform [{[k v] :arg schema :schema :as all} options rest] diff --git a/test/malli/destructure_test.cljc b/test/malli/destructure_test.cljc index 265e65e1a..58d9d54aa 100644 --- a/test/malli/destructure_test.cljc +++ b/test/malli/destructure_test.cljc @@ -45,7 +45,7 @@ :as map}] :schema [:cat :any - [:altn + [:orn [:map [:map [:b {:optional true} :any] ["c" {:optional true} :any] @@ -71,7 +71,7 @@ :bind '[{:keys [a :demo/b] :demo/keys [c]}] :options {::md/required-keys true} :schema [:cat - [:altn + [:orn [:map [:map [:a :any] :demo/b @@ -86,7 +86,7 @@ :options {::md/required-keys true ::md/closed-maps true} :schema [:cat - [:altn + [:orn [:map [:map {:closed true} [:a :any] :demo/b @@ -101,7 +101,7 @@ ::md/closed-maps true ::md/references false} :schema [:cat - [:altn + [:orn [:map [:map {:closed true} [:a :any] [:demo/b :any] @@ -130,7 +130,7 @@ :options {::md/sequential-maps false} ;; no effect here :schema [:cat :any - [:altn + [:orn [:map [:map [:b {:optional true} :any] ["c" {:optional true} :any] @@ -151,7 +151,7 @@ :schema [:cat [:maybe [:cat - [:altn + [:orn [:map [:map [:a {:optional true} :any] [:b {:optional true} :any]]] @@ -159,7 +159,7 @@ [:cat [:= :a] :any] [:cat [:= :b] :any] [:cat [:not [:enum :a :b]] :any]]]]]]] - [:altn + [:orn [:map [:map [:a {:optional true} :any] [:b {:optional true} :any]]] @@ -170,7 +170,7 @@ {:name "Nest right-to-left map syntax" :bind '[{{inner :inner} :outer}] :schema [:cat - [:altn + [:orn [:map [:map [:outer {:optional true} @@ -185,7 +185,7 @@ [:* [:alt [:cat [:= :outer] - [:altn + [:orn [:map [:map [:inner {:optional true} :any]]] [:args [:schema [:* [:alt [:cat [:= :inner] :any] diff --git a/test/malli/experimental_test.clj b/test/malli/experimental_test.clj index bd5a252a8..a1fc3d63d 100644 --- a/test/malli/experimental_test.clj +++ b/test/malli/experimental_test.clj @@ -119,8 +119,12 @@ [[1 2 3 4] 10] [[-1 2 3 4] ::throws]]} {:var #'inner-outer-no-schema - :calls [[[(list :outer [:not-inner])] nil]] - :instrumented [[[(list :outer [:not-inner])] ::throws]]}]) + :calls [[[(list :outer [:not-inner])] nil] + [[{:outer {:inner "here"}}] "here"] + [[{:outer {:not-inner 'foo}}] nil]] + :instrumented [[[(list :outer [:not-inner])] ::throws] + [[{:outer {:inner "here"}}] "here"] + [[{:outer {:not-inner 'foo}}] nil]]}]) (defn -strument! [mode v] (with-out-str