Hey team! I am making a graphql-like query language, that looks something like this:
{"users" {"$" {"where" {"bookshelves.books.title" "The Count of Monte Cristo"}}
"bookshelves" {}}
"books" {}}
Here, I have forms, which have an option-map , and further children.
What I would want here is a combination of keys (to say what $ should be), and map-of, to describe that it can have children.
I wasn't sure how to do this, so the best approach I could think of, was to massage the data into a kind of vector, like:
[["users", {"where" {"bookshelves.books.title" "The Count of Monte Cristo"}}, ["bookshelves", {}, []]],
["books", {}, []]]
So then I could type this vec, like so:
(s/def ::where (s/map-of string? ::triple-model/value))
(s/def ::option-map (s/keys :opt-un [::where]))
(s/def ::form (s/cat
:k string?
:option-map ::option-map
:children (s/coll-of ::inner-form)))
(s/def ::forms (s/coll-of ::form))
Is this the idiomatic way to do things with spec, or would you do it differently?(realized I never responded -- I think this could work! Thank you @smith.adriane)
> I wasn't sure how to do this, so the best approach I could think of, was to massage the data into a kind of vector, like: I'm not totally sure I understand what you're trying to do, but massaging data before validation sounds like an anti-pattern.
maybe something like:
(s/def ::options (s/keys))
(s/def ::form
(s/coll-of
(s/or
:options (s/tuple #{"$"}
::options)
:sub-form (s/tuple string? ::form))
:into {}))