Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Schema Parsing #241

Closed
ikitommi opened this issue Aug 10, 2020 · 6 comments
Closed

Schema Parsing #241

ikitommi opened this issue Aug 10, 2020 · 6 comments
Assignees
Labels
enhancement New feature or request

Comments

@ikitommi
Copy link
Member

ikitommi commented Aug 10, 2020

Currently, m/explain parses the values in align to the Schemas, producing :in and :path paths pointing paths in both values and schemas. This is a good base for generic parsing, e.g. Clojure Spec conform. We could reuse the m/-explain to collect paths for valid & invalid errors. The resulting ~conformed data structure could be self-describing, so that no m/-unexplain would be needed to turn the parsed data structure back into value, like spec has s/unform. This could be achieved using special types/records to mark branching, instead of just maps and vectors (which can't be found from values without per-schema method).

From spec:

(s/def ::name-or-id (s/or :name string?
                          :id   int?))

(s/conform ::name-or-id "abc")
;;=> [:name "abc"]

(s/conform ::name-or-id 100)
;;=> [:id 100]

Would be ~:

(m/parse [:or string? int?] "abd")
;; => #Branch{:path 0, :value "abc"}

(m/parse [:or string? int?] 100)
;; => #Branch{:path 1, :value 100}

And with named branches:

(m/parse [:orn [:string string?] [:int int?]] "abd")
;; => #Branch{:path :string, :value "abc"}

(m/parse [:orn [:string string?] [:int int?]] 100)
;; => #Branch{:path :int, :value 100}

As a bonus, we could present errors in the parse tree in-place.

See also #180.

@ikitommi ikitommi added the enhancement New feature or request label Aug 10, 2020
@borkdude
Copy link
Contributor

I would also like to see something like s/conformer in malli:

https://clojuredocs.org/clojure.spec.alpha/conformer

@ikitommi
Copy link
Member Author

ported the conformer example against the current api: validate + encode + validate + encode.

(def Schema1 [:string {:encode/conform #(mapv str (seq %))}])
(def Schema2 [:sequential {:encode/conform #(apply str %)} [:enum "0" "1"]])

(def conformer (mt/transformer {:name :conform}))

(as-> "1011" $
      (do (println $ "=>" (m/validate Schema1 $)) $)
      (m/encode Schema1 $ conformer)
      (do (println (pr-str $) "=>" (m/validate Schema2 $)) $)
      (m/encode Schema2 $ conformer)
      (= "1011" $))
; 1011 => true
; ["1" "0" "1" "1"] => true
; => true

@ikitommi ikitommi added the Clojurists Together Sponsored by Clojurists Together Q3 2020 label Sep 10, 2020
@ikitommi ikitommi added the blocked Can't be done yet, waiting for some other issue to complete label Oct 5, 2020
@ikitommi ikitommi removed the Clojurists Together Sponsored by Clojurists Together Q3 2020 label Nov 29, 2020
@nilern
Copy link
Contributor

nilern commented Dec 4, 2020

#312 has most of the required logic, but only for regex schemas so I haven't added any public API. Destructuring other schemas should be much more straightforward though.

@nilern nilern self-assigned this Dec 11, 2020
@nilern
Copy link
Contributor

nilern commented Dec 11, 2020

Working on this in #317. Although maybe this should have a separate PR but I'll see how it goes.

@nilern
Copy link
Contributor

nilern commented Dec 11, 2020

And I put zero thought into the design, just trying to get something workable to demonstrate that #317 can also support this. So it is just the obvious cross between malli.core/explainer and clojure.spec.alpha/conform.

@ikitommi ikitommi removed the blocked Can't be done yet, waiting for some other issue to complete label Jan 25, 2021
@ikitommi
Copy link
Member Author

explain & parse can be merged later. This is in master. Thanks!!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants