Skip to content

Commit

Permalink
add ::m/walk-inherit-entry-props
Browse files Browse the repository at this point in the history
  • Loading branch information
frenchy64 committed Aug 16, 2024
1 parent 3924490 commit 262f2fa
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 14 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ We use [Break Versioning][breakver]. The version numbers follow a `<major>.<mino

Malli is in well matured [alpha](README.md#alpha).

## NEXT

* add `::m/walk-inherit-entry-props` to `-walk` for unwrapping `::val` nodes and inheriting their props after walking

## 0.16.3 (2024-08-05)

* `:->` added to default registry, see [documentation](https://github.com/metosin/malli/blob/master/docs/function-schemas.md#flat-arrow-function-schemas).
Expand Down
16 changes: 5 additions & 11 deletions docs/tips.md
Original file line number Diff line number Diff line change
Expand Up @@ -252,20 +252,14 @@ Example 2: if `:cost` is missing, try to calculate it from `:price` and `:qty`:

## Walking Schema and Entry Properties

1. walk entries on the way in
2. unwalk entries on the way out

```clojure
(defn walk-properties [schema f]
(defn walk-properties [?schema f & args]
(m/walk
schema
?schema
(fn [s _ c _]
(m/into-schema
(m/-parent s)
(f (m/-properties s))
(cond->> c (m/entries s) (map (fn [[k p s]] [k (f p) (first (m/children s))])))
(m/options s)))
{::m/walk-entry-vals true}))
(apply m/-update-properties (m/-set-children s c) f args))
{::m/walk-inherit-entry-props true
::m/walk-entry-vals true}))
```

Stripping all swagger-keys:
Expand Down
13 changes: 10 additions & 3 deletions src/malli/core.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
(-transformer [this transformer method options]
"returns a function to transform the value for the given schema and method.
Can also return nil instead of `identity` so that more no-op transforms can be elided.")
(-walk [this walker path options] "walks the schema and it's children, ::m/walk-entry-vals, ::m/walk-refs, ::m/walk-schema-refs options effect how walking is done.")
(-walk [this walker path options] "walks the schema and it's children, ::m/walk-entry-vals, ::m/walk-refs, ::m/walk-schema-refs, ::m/walk-inherit-entry-props options effect how walking is done.")
(-properties [this] "returns original schema properties")
(-options [this] "returns original options")
(-children [this] "returns schema children")
Expand Down Expand Up @@ -329,8 +329,15 @@
(defn -inner-indexed [walker path children options]
(-vmap (fn [[i c]] (-inner walker c (conj path i) options)) (map-indexed vector children)))

(defn -inner-entries [walker path entries options]
(-vmap (fn [[k s]] [k (-properties s) (-inner walker s (conj path k) options)]) entries))
(defn -inner-entries [walker path entries {::keys [walk-inherit-entry-props] :as options}]
(-vmap (fn [[k s]]
(let [s' (-inner walker s (conj path k) options)]
(if (and walk-inherit-entry-props
(schema? s')
(= ::val (type s')))
[k (-properties s') (-deref s')]
[k (-properties s) s'])))
entries))

(defn -walk-entries [schema walker path options]
(when (-accept walker schema path options)
Expand Down
35 changes: 35 additions & 0 deletions test/malli/util_test.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -1044,3 +1044,38 @@
{}
{:registry (merge (mu/schemas) (m/default-schemas))}
(mt/default-value-transformer {::mt/add-optional-keys true})))))

;; not quite ready. does not walk inside registries and pointers expand
;; when printing their properties.
(defn walk-properties [?schema f & args]
(m/walk
?schema
(fn [s _ c _]
(apply m/-update-properties (m/-set-children s c) f args))
{::m/walk-inherit-entry-props true
::m/walk-entry-vals true}))

(defn remove-swagger-keys [p]
(not-empty
(reduce-kv
(fn [acc k _]
(cond-> acc (some #{:swagger} [k (-> k namespace keyword)]) (dissoc k)))
p p)))

(deftest walk-properties-test
(is (= [:map {:title "Organisation name"} [:ref :string] [:kikka :string]]
(m/form
(walk-properties
[:map {:title "Organisation name"}
[:ref {:swagger/description "Reference to the organisation"
:swagger/example "Acme floor polish, Houston TX"} :string]
[:kikka [:string {:swagger {:title "kukka"}}]]]
remove-swagger-keys))))
(is (= [:map {:foo 1} [:a {:foo 1} [:int {:foo 1}]]]
(m/form (walk-properties [:map [:a :int]] assoc :foo 1))))
(is (= [:map [:a :int]]
(m/form (walk-properties [:map {:foo 1} [:a {:foo 1} [:int {:foo 1}]]] dissoc :foo))))
(is (= [:map {:foo 1 :registry {:foo :int}} [:a {:foo 1} [:int {:foo 1}]]]
(m/form (walk-properties [:map {:registry {:foo :int}} [:a :int]] assoc :foo 1))))
(is (= [:map {:registry {:foo :int}} [:a :int]]
(m/form (walk-properties [:map {:foo 1 :registry {:foo :int}} [:a {:foo 1} [:int {:foo 1}]]] dissoc :foo)))))

0 comments on commit 262f2fa

Please sign in to comment.