metosin / malli

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

Allow more than one pair of `key-schema` `value-schema` for `:map-of` #881

Open DeLaGuardo opened 1 year ago

DeLaGuardo commented 1 year ago
[:map-of {}
  :keyword :int
  [:re #"^([a-z][a-z0-9]*)+(-[a-z0-9]+)*\\-ext$"] [:map ,,,]]

Something similar exists in json-schema:

{
  "type": "object",
  "patternProperties": {
    "^([a-z][a-z0-9]*)+(-[a-z0-9]+)*\\-ext$": {},
    "^([a-z][a-z0-9]*)+(-[a-z0-9]+)*\\-ext-definition$": {}
  },
  "additionalProperties": false
}
cap10morgan commented 1 year ago

@DeLaGuardo I've been exploring a similar thing in the #malli Clojurians Slack channel and was going to open an issue for it, but this might cover it already. Are you asking for and semantics (i.e. every key must conform to every key schema and every value must conform to every value schema) or or semantics (i.e. every key must conform to at least one key schema and every value must conform to a value schema that is paired to a key schema its key conforms to)?

cap10morgan commented 1 year ago

As confirmed in Slack, it's or semantics. And thus this is also what I'm looking for.

@ikitommi could you explain a little more about why don't want this to be added to :map-of? It seems by far the most intuitive and natural place for it, and could be done in a backwards-compatible way by differentiating between [:map-of :key-schema :value-schema] (current syntax w/ no inner vectors) and [:map-of [:key-schema-1 :value-schema1] [:key-schema2 :value-schema2] ...].

DeLaGuardo commented 1 year ago

Probably because then it would not be possible to differentiate between [:map-of [:string {}] [:string {}]] and the new form. I would agree, there should be a new syntax to describe such maps.

[:map-with {}
  [:key-schema-1 {:min 1 :max 10} :value-schema-1]
  [:key-schema-2 {} :value-schema-2]]

With that notation, it will be possible to say that keys like :key-schema-1 should be present N times.

cap10morgan commented 1 year ago

@DeLaGuardo Ohhh... right. You do put them in vecs when you need to add properties to the key and/or value schemas. I forgot about that. OK, so new schema type it is. Thoughts on a good name?

DeLaGuardo commented 1 year ago

I edited my comment after you asked for a name, sorry) :map-with to highlight that the schema is about to describe a map with constraints added to certain keys