I've found myself in a need to validate a list with the rough shape of:
- The list contains structs/maps of different types.
- Each of the types has a minimum and maximum amount of occurrences allowed (specified by an external non-machine-readable schema).
- Some of the structs/maps embed others in a tree-like children list attribute.
So, something like this:
[
%{tag: "00", ...},
%{tag: "11", ...},
%{tag: "12", ..., children: [%{tag: "16", ...}, %{tag: "21", ...}]},
# ...A lot more recursive rules like these follow...
%{tag, "99", ...}
]
In this example, tags 00
and 11
and 99
can appear once and only once, while the tag 12
can appear 1..9999
times but its children must appear only once. There are other structs/maps that must be present but some of their children are optional (0..1
occurrences).
I was thinking of devising my own code to validate such lists by having a schema like this:
[
%{tag: "00", limit: 1..1},
%{tag: "11", limit: 1..1},
%{tag: "12", limit: 1..9999, children: [%{tag: "16", limit: 1..1}, %{tag: "21", limit: 1..1}, %{tag: "26", limit: 1..1}]},
%{tag: "99", limit: 1..1},
]
...etc. The point being, have a hierarchical structure that:
- Gives you a pattern to match on -- in this case it's
%{tag: x} when is_binary(x) and x in ~w[00 11 12 16 21 99]
, and
- Assert on how many times the given pattern can occur.
As the author of the library pointed out in ElixirForum (https://elixirforum.com/t/exvalibur-smart-validation-in-elixir/17677/14), this is akin to XML Schema (XSD), although I'd like to be able to specify such a validation schema by hand as well.
I admit I haven't fully cleared all the specifics inside my head yet -- I tried several recursive approaches and some of them work but they irritated me by being too specialised. So I was wondering if we can generalise a solution inside this library.