Liking cljdoc? Tell your friends :D

malli-select

Clojars Project cljdoc badge

Create subschemas of malli-schemas using a spec2-inspired select notation.

It's based on Rich Hickey's ideas from his talk "Maybe Not" about how spec-alpha2 might allow for schema reuse.

Quickstart

Try it out using deps-try:

$ deps-try io.github.eval/malli-select metosin/malli

user=> (require '[malli-select.core :as ms])
user=> (def Person
         [:map
           [:name string?]
           [:age pos-int?]
           [:addresses [:vector [:map
                                  [:street string?] [:zip string?]]]]])

;; require :name, everything else is optional
user=> (ms/select Person [:name])
[:map
 [:name string?]
 [:age {:optional true} pos-int?]
 [:addresses
  {:optional true}
  [:vector
   [:map
    [:street {:optional true} string?]
    [:country {:optional true} string?]]]]]

;; *if* any address is provided, it should at least have :street
user=> (ms/select Person [{:addresses [:street]}])
[:map
 [:name {:optional true} string?]
 [:age {:optional true} pos-int?]
 [:addresses
  {:optional true}
  [:vector
   [:map [:street string?] [:country {:optional true} string?]]]]]

;; example valid data:
;; {}, {:addresses []}, {:addresses [{:street "Main"}]}
;;
;; example invalid data:
;; {:addresses nil}, {:addresses [{}]}, {:addresses [{:street "Foo" :country :se}]}

;; any address provided should be a full address
user=> (ms/select Person [{:addresses ['*]}])
;;
;; require all attributes of a person (shallow, i.e. address attributes become optional)
user=> (ms/select Person ['*])
;; example valid data:
;; {:name "Foo" :age 18 :addresses [{}]}


;; remove any optional attribute
user=> (ms/select Person [{:addresses ['*]}] {:prune-optionals true})
;; or shorter:
user=> (ms/select Person ^:only [{:addresses ['*]}])
;; example valid data:
;; {:name :not-a-string}
;;
;; Typically you'd use this to generate only specific data:
user=> (require '[malli.generator :as mg])
user=> (mg/generate (ms/select Person ^:only [:name]))
{:name "sNeLdUI5KtPw"}

;; selecting something not contained in the schema:
user=> (ms/select Person [:a])
Execution error (AssertionError) at dk.thinkcreate.malli-select/select (malli_select.clj:175).
Assert failed: Selection contains unknown paths: ([:a])

Available:
([:addresses] [:age] [:name] [:addresses :street] [:addresses :zip])

(empty? invalid-selection-paths)
;; bypass this check:
user=> (ms/select Person [:a] {:verify-selection false})

See the tests for more.

LICENSE

Copyright (c) 2023 Gert Goet, ThinkCreate. Distributed under the MIT license. See LICENSE.

Can you improve this documentation?Edit on GitHub

cljdoc is a website building & hosting documentation for Clojure/Script libraries

× close