Let's say I'm passing a delayed value between functions - is there a Malli type for that as an opaque box? What about a way to declare (even just for humans) what type the contents are?
IIUC the former could be delay?
Not sure I've seen a [:delay T] schema yet.
something like this might work
(defn -delay-schema []
(m/-proxy-schema {:type :delay
:fn (fn [p c o]
(m/-check-children! :delay p c 1 1)
(let [c (mapv #(m/schema % o) c)]
[c (map m/form c) (m/schema delay? o)]))}))I think it does both the things you want
Generator is something like:
(defmethod mg/-schema-generator :delay [schema options]
(gen/fmap
#(delay %)
(mg/generator (first (m/children schema options)) options)))
Thanks for that, how would I go about calling it though, am I holding it wrong?
(require '[malli.core :as m])
(require '[malli.registry :as mr])
(defn -delay-schema []
(m/-proxy-schema {:type :delay
:fn (fn [p c o]
(m/-check-children! :delay p c 1 1)
(let [c (mapv #(m/schema % o) c)]
[c (map m/form c) (m/schema delay? o)]))}))
(binding [mr/*registry* {:string (m/-string-schema)
:delay (-delay-schema)}]
(m/validate [:delay :string] (delay "x")))
;;=>
Unhandled clojure.lang.ExceptionInfo
:malli.core/invalid-schema
{:type :malli.core/invalid-schema,
:message :malli.core/invalid-schema,
:data {:schema :delay, :form [:delay :string]}}
core.cljc: 157 malli.core$_exception/invokeStatic
core.cljc: 157 malli.core$_exception/invoke
dev.clj: 18 malli.dev/-capture-fail!/fn/-fail!
...try mr/set-default-registry! instead
the dynamic registry (supporting the *registry* binding is not enabled by default.
fwiw I fleshed it out a bit here https://github.com/metosin/malli/pull/1171
Thanks you guys
I am still hitting the same issue, though. Not sure what I am doing wrong, seems like this should work:
(require '[malli.registry])
(require '[malli.core :as m])
(defn -delay-schema [_]
(m/-proxy-schema {:type :delay
:fn (fn [{:keys [force] :as p} c o]
(m/-check-children! :delay p c 1 1)
(let [c (mapv #(m/schema % o) c)
v (m/-validator (first c))]
[c (map m/-form c) (m/schema [:fn (fn [d]
(if (delay? d)
(if (or (realized? d) force)
(v @d)
true)
false))]
o)]))}))
(malli.registry/set-default-registry! {:string (m/-string-schema)
:delay (-delay-schema nil)})
(m/validate :string "foo") ;; => true
;; (mc/validate :int "foo") ;; this throws, so I must be using the default registry
(try (m/validate [:delay :string] (delay "foo"))
(catch Exception e (ex-data e)))
;;=> {:type :malli.core/invalid-schema,
;; :message :malli.core/invalid-schema,
;; :data {:schema :fn, :form [:fn #function[user/-delay-schema/fn--201005/fn--201009]]}}it's defined in terms of :fn for now via proxy-schema
should look more like -collection-schema in the ideal impl
Of course, this is why it was failing with (m/schema delay? ...) before too!
ha glad you asked
oh, do you mean this was the original problem you were asking about, or trying the first impl?
Actually for the first one, I'm not sure how (mc/schema delay? o) could work without adding delay? somewhere
Fleshed out :delay, :future, and :promise schemas https://github.com/metosin/malli/pull/1171