malli icon indicating copy to clipboard operation
malli copied to clipboard

Homogeneous map with specific keys.

Open kovasap opened this issue 2 years ago • 7 comments

I'm looking for a way to encode a homogeneous map that needs specific keys in malli. For example,

{:id 1 :data1 1.0 :data2 1.0 ...}

In this example, I want to be able to say "my map has an [:id int], and the rest of the values are :keyword :double pairs".

Currently, I see that I could use :map and just enforce my specific keys (and keep the map open), but I really want to get validation that the rest of the entries are in fact :keyword :double pairs. :map-of doesn't seem to work because then I can only specify the :keyword :double pairs and not my [:id :int].

Any ideas how I could accomplish this?

kovasap avatar Apr 02 '22 18:04 kovasap

Try [:and [:map [:id int?]] [:map-of :keyword double?]]. It doesn't seem to generate very rich values though.

Playground

frenchy64 avatar Apr 10 '22 15:04 frenchy64

Ah that makes sense! That works for me. The value generation is less important for me than the validation.

kovasap avatar Apr 10 '22 17:04 kovasap

Actually that doesn't work: playground. The :map keys must also conform to the :map-of spec in the :and solution. This works in your example because an int conforms to a double i guess?

kovasap avatar Apr 10 '22 17:04 kovasap

Ah yes, probably a cljs thing. Another two options are to broaden the :map-of schemas to include the :map ones (less accurate validation) or to use :fn to manually dissoc the known keys before validating (perhaps worse error messages).

I think in all cases you might want a custom generator anyway.

-------- Original Message -------- On Apr 10, 2022, 13:46, Kovas Palunas wrote:

Actually that doesn't work: playground. The :map keys must also conform to the :map-of spec in the :and solution. This works in your example because an int conforms to a double i guess?

— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you commented.Message ID: @.***>

frenchy64 avatar Apr 10 '22 18:04 frenchy64

For posterity: it seems like there are two things we could fix here:

  1. make the :map-of vs :map thing work in CLJS as it does in CLJ
  2. support extra keys for maps like plumatic schema does. See #43

opqdonut avatar May 31 '22 11:05 opqdonut

I am running into the same problem, but when i use :map and :map-of together in different ways :and mu/union :or ... i am having trouble making sense of the schema.

i feel like the high level concept is closed map unioned with map-of, but in my case there is a lot of conflict (i'm converting a json schema to malli, and json schema is a pretty awful spec)

  (m/schema
    (mu/union
      [:map-of keyword? :string]
      [:map {:closed true}
       [:optional {:optional true} [:enum :a :b]]
       [:specified :int]]))

i feel that closed map is needed, and if you can see that my map-of is a different type than my closed map. so, for each map-entry to be valid, test against both/all schemas. json schema supports 3 or more unions for additional properties. then, there are also required keys in the spec, so things get more tricky to understand.

also, i see in the code union is a merge, i'm not sure this makes sense to me for this concept of a map.

i saw that there is a sibling thread for this topic that would have us doing something like

[:map {:closed [:map-of keyword? :string]}
 [:optional {:optional true} [:enum :a :b]]
 [:specified :int]]

i think that's probably enough to solve this issue.

the malli.core code is very very hard for me to understand. i'm also trying to use the malli.generator code, and i would like this feature to work in both validation/generation. any help would be very well received.

boxxxie avatar Jul 24 '22 13:07 boxxxie

[:and
 [:fn (fn [m]
        (->>
          (dissoc m :specified :optional :required)
          (m/validate (m/schema [:map-of keyword? string?]))))]
 [:map
  [:required [:enum :a :b]]
  [:optional {:optional true} [:enum :a :b]]
  [:specified :int]]]

this is a workaround that i have used, mainly because i have struggled a lot to debug/edit malli.core code

boxxxie avatar Jul 25 '22 13:07 boxxxie

Duplicate of #43

ikitommi avatar Mar 15 '23 08:03 ikitommi