Fork me on GitHub
#malli
<
2022-09-08
>
Ferdinand Beyer07:09:03

It seems that I can't use recursive schemas in regular expression schemas?

(def selector-schema
  (malli/schema
   [:schema {:registry {::selector [:and vector? [:+ [:cat keyword? [:? [:ref ::selector]]]]]}}
    [:ref ::selector]]))

(malli/validate selector-schema [:foo [:bar]])
; Execution error (ExceptionInfo) at malli.core/-fail! (core.cljc:138).
; :malli.core/potentially-recursive-seqex [:ref :user/selector]
Is there another way to specify this? I basically want to specify a vector of keywords, that are optionally followed by a vector that conforms to the same spec...

ikitommi07:09:10

you can’t inline the recursive references (reasoning https://github.com/metosin/malli/blob/master/src/malli/impl/regex.cljc), but you can use them, with explicit :schema wrapping, e.g.

(def selector-schema
  (malli/schema
   [:schema {:registry {::selector [:and vector? [:+ [:cat keyword? [:? [:schema [:ref ::selector]]]]]]}}
    [:ref ::selector]]))

ikitommi07:09:54

there was a discussion of auto-wrapping :refs here, but it might be more confusing.

ikitommi07:09:58

Your welcome 🙂

Ferdinand Beyer07:09:23

I wonder if we should place a hint to that somewhere in the README. Happy to give it a try and PR

Ferdinand Beyer07:09:50

I was about to give up already, would never have guessed to wrap it in [:schema]

ikitommi07:09:54

> As all these examples show, the “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: >

(m/validate
>   [:cat [:= :names] [:schema [:* string?]] [:= :nums] [:schema [:* number?]]]
>   [:names ["a" "b"] :nums [1 2 3]])
> ; => true
> 
> ;; whereas
> (m/validate
>   [:cat [:= :names] [:* string?] [:= :nums] [:* number?]]
>   [:names "a" "b" :nums 1 2 3])
> ; => true
>

ikitommi07:09:15

that’s on the README, which is bit overgrown…

Ferdinand Beyer07:09:38

Note to self: Always read the whole section