Skip to content

Commit

Permalink
mu/deref-recursive
Browse files Browse the repository at this point in the history
  • Loading branch information
ikitommi committed Jan 2, 2024
1 parent 5fc4005 commit 9254eb6
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 30 deletions.
30 changes: 0 additions & 30 deletions docs/tips.md
Original file line number Diff line number Diff line change
Expand Up @@ -539,33 +539,3 @@ Example utility to convert schemas recursively:
; [:int {:gen/elements [1 2 3]}]
; :string]]]]]
```

## De-reference schemas from a registry

When transforming schemas, if they are provided by a registry, it's useful to dereference them first.

```clojure
(defn deref-recursive
"deref all schemas at all levels so the resulting schema has no registry references"
[schema]
(m/walk schema
(m/schema-walker m/deref-all)
{::m/walk-schema-refs true
::m/walk-refs true}))

(def smart-phone
(m/schema "smart-phone"
{:registry (merge (m/default-schemas)
{"smart-phone" [:map
[:type [:enum :android :iphone]]
[:connector "connector"]]
"connector" [:enum :usb-c :micro-usb :lightning]})}))

(deref-recursive smart-phone)
=> [:map
[:type [:enum :android :iphone]]
[:connector [:enum :usb-c :micro-usb :lightning]]]
```

The fully de-referenced schema is plain data which is much easier to transform.

14 changes: 14 additions & 0 deletions src/malli/util.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,20 @@
([?schema value options]
((data-explainer ?schema options) value [] [])))

(defn deref-recursive
"derefs all schemas at all levels. Does not walk over `:ref`s."
([?schema]
(deref-recursive ?schema nil))
([?schema options]
(let [schema (m/schema ?schema options)]
(-> (m/walk schema (fn [schema _ children _]
(cond
(= :ref (m/type schema)) schema
(m/-ref-schema? schema) (first children)
:else (m/-set-children schema children)))
{::m/walk-schema-refs true})
(m/deref-all)))))

;;
;; EntrySchemas
;;
Expand Down
18 changes: 18 additions & 0 deletions test/malli/util_test.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -990,3 +990,21 @@
(mu/assoc-in [:foo :bar] :int)
(mu/assoc-in [:foo :baz] :int)
(mu/closed-schema)))))

(deftest deref-recursive-test
(let [schema [:schema {:registry {::user-id :uuid
::address [:map
[:street :string]
[:lonlat {:optional true} [:tuple :double :double]]]
::user [:map
[:id ::user-id]
[:name :string]
[:friends {:optional true} [:set [:ref ::user]]]
[:address ::address]]}}
::user]
expected [:map
[:id :uuid]
[:name :string]
[:friends {:optional true} [:set [:ref :user/user]]]
[:address [:map [:street :string] [:lonlat {:optional true} [:tuple :double :double]]]]]]
(= expected (m/form (mu/deref-recursive schema)))))

0 comments on commit 9254eb6

Please sign in to comment.