malli

https://github.com/metosin/malli :malli:
oly 2021-07-05T07:14:29.293Z

is there a way to have different map layouts, I wanted to do something like this

[:map [:coord [:or 
               [:map {:closed true}]
               [:map {:closed true} [:x int? :y int?]]]]]
{:coord {}}
{:coord {:x 1 :y 1}}
I know I can make the whole map optional but what about allowing an empty map or a map with fixed keys, I tried a few things but could not find a way.

alpox 2021-07-05T07:44:40.293600Z

@oliver.marks I think this works if you use for the second :map:

[:map {:closed true} [:x int?] [:y int?]]

oly 2021-07-05T07:47:17.295400Z

yeah that works for the second map, just not sure how to make it work also for an empty map I tried putting optional in various places and tried :or and a few other things oh I might have missed some brackets above but its more an an illustration of one of the methods I tried

oly 2021-07-05T07:48:16.296400Z

[:map {:closed true :optional true} [:x int?] [:y int?]]
also tried this but that does not work, I know I could make the :x and :y keys optional but really I want an all or nothing method

alpox 2021-07-05T07:49:26.297100Z

I tried it with your :or above and that worked (after adding the missing brackets)

alpox 2021-07-05T07:52:54.298400Z

oly 2021-07-05T07:53:00.298900Z

this passes ? {:coord {}} when I run it through m/valid i get missing keys or I was yesterday when I was testing πŸ˜›

oly 2021-07-05T07:53:52.299400Z

nice, I will re check what I have maybe there was a different error which I did not spot

oly 2021-07-05T07:56:19.299700Z

@alpox

[:map [:coord [:or 
               [:map {:closed true}]
               [:map {:closed true}
               [:x {:optional false} int?]
               [:y {:optional false} int?]]]]]

oly 2021-07-05T07:56:50.300400Z

what about that, I think because the key do not have the optional map the :or is irrelevant anyway

oly 2021-07-05T07:58:27.301900Z

although perhaps thats it, perhaps its optional thats messing me up looking at your screenshot again I can see it fails when one of the keys are missing

oly 2021-07-05T08:09:05.302900Z

@alpox thanks for your rubber ducking, not an issue with malli I had 2 schmeas with similar name and was updating the wrong one πŸ˜•

alpox 2021-07-05T08:10:28.303100Z

Oups πŸ™‚ np

Ben Sless 2021-07-05T08:29:47.304400Z

I constantly get the feeling that I'm missing a schema to talk about map schemas in terms of key-value pairs

Ben Sless 2021-07-05T08:30:37.305100Z

an annoying example to implement is mutual exclusion, such as a map which can have x, y and (z or u)

Ben Sless 2021-07-05T08:30:48.305500Z

where z and u have different value types, too

ikitommi 2021-07-05T12:34:03.314900Z

Hear hear. I think something like malli-keys-relations should be there. With qualified keywords, it’s less boilerplate (but, still has):

[:or 
 [:map ::x ::y ::z]
 [:map ::x ::y ::u]]

ikitommi 2021-07-05T12:34:51.315500Z

spec-style would be:

[:map ::x ::y [:keys/or ::y ::u]]

ikitommi 2021-07-05T12:36:06.316400Z

maybe:

[:and
 [:map ::x ::y ::z ::u]
 [:keys/or ::z ::u]]

ikitommi 2021-07-05T12:39:55.316800Z

… and the mandatory JSON Schema way for this: https://json-schema.org/understanding-json-schema/reference/conditionals.html

Ben Sless 2021-07-05T12:49:33.318600Z

JSON Schema's BNF was one of the motivations for it

Ben Sless 2021-07-05T12:50:15.319500Z

> map which contains at least one ::x where ::x is [:or [:x int?] [:y float?]]

Ben Sless 2021-07-05T12:57:18.320600Z

If we had it we could define JSON Schema with malli (translating the ebnf is straightforward), then define encoders and decoders to transform between the two

ikitommi 2021-07-05T16:28:41.324100Z

added a video of the new function instrumention. three apis: advanced, normal users and for the lazy: https://github.com/metosin/malli/pull/471

πŸŽ‰ 4
ikitommi 2021-07-05T16:28:52.324400Z

comments welcome