metosin / malli

High-performance data-driven data specification library for Clojure/Script.
Eclipse Public License 2.0
1.51k stars 212 forks source link

Implement malli.util/select, similar to spec-alpha2/select #724

Open hgranthorner opened 2 years ago

hgranthorner commented 2 years ago

I think it would be pretty great to have a malli equivalent to the spec-alpha2/select. For those that don't know, select would take a schema and a keyset, and mark all keys not in the keyset as optional. For example:

(malli.util/select [:map [:a int?] [:b string?]] [:a])
=> [:map [:a int?] [:b {:optional true} string?]]

select should also allow for selecting subkeys. For example, here we mark the root level key as optional, but if it exists, :c is required:

(malli.util/select [:map [:a int?] [:b [:map [:c string?]]]] [:a {:b [:c]}])
=> [:map [:a int?] [:b {:optional true} [:map [:c string?]]]]

I think this would be great, and serve much the same need as the spec-alpha2/select function. I've taken a couple cracks at implementing this myself, but haven't quite figured it out.

hgranthorner commented 2 years ago

I may have a working example here, but is almost definitely missing some edge cases and can definitely be implemented much more easily/performantly... I'm just not sure how.

bortexz commented 2 years ago

Hacked around another implementation of select that seems to work, in case anyone's interested: https://gist.github.com/bortexz/a9e253ab7b7ba3815409bb869f91c846

Edit: We could have select-eql, require-eql and optional-eql, equivalents to *-keys that operate on EQL instead of keys vector

NoahTheDuke commented 2 years ago

Oh good call with the gist, here's my implementation, which makes all non-selected keys optional.

Yutsa commented 1 year ago

Any updates on this ? Watched the "Maybe not" talk by Rich Hickey and having composability of specs looks really good

crimsonhawk47 commented 1 year ago

I'm also interested in this

eval commented 1 year ago

I released https://github.com/eval/malli-select. It allows for selecting across map-of, vector etc. (e.g. [{:addresses [:street]}]), it will assert correct paths, and optional attributes can be pruned (to aid data generation). Feeback welcome!