Closed billylanchantin closed 10 months ago
You can basically already do this with just a few more lines of code from what you have above. Something like:
@pets [
%{value: :cat, doc: "feline"},
# ...
]
@schema [
pet: [
type: {:in, Enum.map(@pets, & &1.value)},
doc: "Type of pet. Must be one of #{Enum.map_join(@pets, ", ", & &1.doc)}"
]
]
In order for this library to stay nimble, I'd say something like the code above is probably the best approach. If we introduce NimbleOptions.Choice
, the slope gets pretty slippery and we might start adding a ton of similar things.
Thanks for the proposal anyways! 💟
I hear you on remaining nimble! So no worries is this is still rejected. But do note that your proposed solution is not quite what I was going for.
You'd want something more like:
@schema [
pet: [
type: {:in, Enum.map(@pets, & &1.value)},
doc: """
Type of pet.
Must be one of:
#{Enum.map_join(@pets, "\n\n", &" * `#{inspect(&1.value)}` - #{&1.doc}")}
"""
]
]
But then you start running into indentation issues and it gets messy.
And it also feels like I'm reinventing what ought to be fairly fundamental -- I think I want this literally every time I have a list of atoms as options. If an element of a schema can self-document via :doc
, why not an element of an {:in, ...}
?
However, again, I do hear you on remaining Nimble. I can definitely make the map_join
version work if need be :)
@billylanchantin this sets a "dangerous" precedent though. We don't change documentation for any other type. For example, we don't say something like "must be an integer" if you use :integer
as the type. So, this would be a first, and would start what I think would be a slippery slope. I suggest to add helpers to your application that do something like the code you showed above.
Thanks again!
Sure thing! And thanks for the explanation :)
Problem
A list of choices is already supported via
{:in, ...}
. Unfortunately, there's no easy way to document the choices.Example:
If you do this, there is no reference in the docs to the actual values the
:pet
key can assume. If you want to document that, you need to do so manually:This isn't ideal. And it has a habit of growing out of sync with the actual values.
Proposal
We add a struct of some sort that allows choices to self-document. For example:
Then if the type is
{:in, ...}
and the element is a%NimbleOptions.Choice{}
(or whatever name makes sense), then the docs builder can add the "Must be one of..." part automatically.