PD: Let's continue this thread on the github ticket. Saludos, Nahuel Greco.
On Mon, Aug 25, 2014 at 6:51 PM, Nahuel Greco <[email protected]> wrote: > Instead of defining Step superschema can you simply do: > > (s/validate something (get-schema step)) > > ?? > > If you need more than that, for example, if you need a named schema to use > it in function signatures, then I think you have two options: > > 1- Define a superschema just like in your example, but using the > multimethod instead of a literal: > > (defmulti get-schema :type) > (defmethod get-schema :http [v] {:url s/Str}) > (defmethod get-schema :delay [v] {:seconds s/Int}) > > (def Step > (apply s/conditional > (flatten (for [type (keys (methods get-schema))] > [#(= (:type %) type) > (get-schema {:type type})])))) > > The problem here is you need to have all the methods already defined by > your api users at the moment of defining the Step "superschema". > > 2- Generalize the problem, you need to define an Schema that resolves > dinamically to another based on the value. s/conditional does something > like that but is not sufficient. I think is an uncovered corner case in > Prismatic Schema, you can try doing something like this: > > (defrecord SchemaResolver [resolve-fun] > s/Schema > (walker [this] > (fn [value] (s/walker (resolve-fun value)))) > (explain [this] > ;; not implemented > )) > > (defmulti get-schema :type) > > (def Step (SchemaResolver. get-schema)) > > ;; defmethods can be next, > ;; because the schema will be resolved dinamically on each > ;; validation. > (defmethod get-schema :http [v] {:url s/Str}) > (defmethod get-schema :delay [v] {:seconds s/Int}) > > But this will not work because Prismatic Schema does some tricks with > dynamic binding when calling walker, so you can't simply delegate this way. > Maybe you need to discuss this in the ticket. > > > > Saludos, > Nahuel Greco. > > > On Mon, Aug 25, 2014 at 7:41 AM, Laurens Van Houtven <[email protected]> wrote: > >> Hi Nahuel, >> >> >> On Saturday, August 23, 2014 7:23:42 PM UTC+2, nahuel wrote: >>> >>> what about: >>> >>> (defmulti step-handler :type) >>> (defmulti get-schema :type) ;; returns the schema >>> >>> And make your users implement both? Remember schemas are first-class >>> values. >>> >> >> The difficulty I'm having is figuring out how to then embed these schemas >> into another schema. (The reason I want *that* is because these steps are >> composed into different schemas, and I'd like to check the superschema.) >> Ideally I would end up with something like: >> >> (def Step >> (s/conditional >> #(= (:type %) :http) {:the :http :schema :here} >> #(= (:type %) :delay) {:the :delay :schema: :here})) >> >> ... except with the keys and schemas coming out of the multimethod (or >> whatever) instead of being a literal :) >> >> I guess I could do that with some extended macrology hackery for now; if >> my defstep macro stashes all of the schemas in a ref somewhere, I can then >> expand to the above code example :) >> >> I've created a ticket for this on prismatic/schema: >> https://github.com/Prismatic/schema/issues/140 >> >> thanks again, >> lvh >> >> -- >> You received this message because you are subscribed to the Google >> Groups "Clojure" group. >> To post to this group, send email to [email protected] >> Note that posts from new members are moderated - please be patient with >> your first post. >> To unsubscribe from this group, send email to >> [email protected] >> For more options, visit this group at >> http://groups.google.com/group/clojure?hl=en >> --- >> You received this message because you are subscribed to the Google Groups >> "Clojure" group. >> To unsubscribe from this group and stop receiving emails from it, send an >> email to [email protected]. >> For more options, visit https://groups.google.com/d/optout. >> > > -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to [email protected] Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to [email protected] For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. For more options, visit https://groups.google.com/d/optout.
