Fork me on GitHub
#malli
<
2023-10-10
>
cheewah14:10:57

Hi, am wondering if it is possible to define custom validation function that takes in optional params, and then refer to it somewhere else? Something like :vfunc below.

(def schema {:registry (mr/composite-registry
                        m/default-registry
                        {:vfunc [:fn (fn [v & opts] true)] ; opts = {:min 10}
                         :./msg [:and [:map {:closed true}
                                       [:int32_val {:optional true} int?]]
                                      [:vfunc {:min 10}]]})}) ; use vfunc and pass in {:min 10} as optional argument

(m/validate [:ref :./msg] {:int32_val 1} schema)
(above code doesn't work as it is invalid schema, but it expresses what I am trying to achieve)

escherize15:10:03

Is there a third party library or other similar thing for putting malli schemas on defprotocols, defrecords, and/or multimethods?

👀 3
escherize17:10:21

(or am I going to be the one to do it?) 😉

escherize18:10:23

granted, multimethods aren’t actually required to return the same shape, but neither are functions and having malli-ized defns (and fns) is pretty nice.

Stig Brautaset22:10:56

If Malli supported schemas on protocols I'd have a strong case for adopting it at work. We have quite a lot of code to work around the inability to put Specs on protocols.

hifumi12306:10:11

IIRC pre/post conditions are intentionally not supported in protocol methods. The workaround is to make an instrumented function wrapping the protocol method. i.e. given -f you define f with pre/post conditions

escherize16:10:35

@U051V5LLP thanks for posting that, very helpful

1
steveb8n21:10:42

Q: when using nested schemas from a registry, is there a way to recursively deref all the way down? I can see something like this in mu/subschemas but I just want everything local. this would make transformations much easier

ambrosebs01:10:15

malli.core/deref-all ?

steveb8n10:10:56

Unfortunately doesn't recurse multiple levels

eval202011:10:10

This?

(let [schema [:schema {:registry {"More"  [:map
                                             [:more boolean?]]
                                    "Other" [:map
                                             [:other boolean?]
                                             [:more "More"]]}}
                [:map
                 [:this boolean?]
                 [:that "Other"]]]]
    (m/walk schema (m/schema-walker m/deref-all)
            {::m/walk-schema-refs true ::m/walk-refs true}))
;; => [:map [:this boolean?] [:that [:map [:other boolean?] [:more [:map [:more boolean?]]]]]]

steveb8n22:10:06

@U04V6FEES thank you!! that is exactly what I needed

👍 1
steveb8n22:10:33

feels like that should be a util fn or in docs somewhere. very useful when working with deep registries

steveb8n21:10:18

excellent suggestion. I’ll pay forward and will submit a PR for it

metal 1
gratitude-thank-you 1