This is a game changer for Elixir, finally we have a better way to define composable validations with a nice syntax.
Great work @phcurado
This is a game changer for Elixir, finally we have a better way to define composable validations with a nice syntax.
Great work @phcurado
Zoi is reaching 10k downloads on hex.pm I would like to thank everyone who has used and supported this library. Every feedback has been taken seriously and helped to improve this project.
These are the main features that have been added based on feedback:
And many more added into the project’s internals!
I created a blog post where I walk through some of the Zoi features and the reason behind creating this library.
Don’t forget to check the git repo and if you have any feedback or suggestions, feel free to open an issue or a PR.
Hello
and congrats!
Thanks again for featuring Oaskit!
How hard was it to implement the typespec generation, like for instance for a map where values are lists of integers? I’m thinking of implementing this for the JSON schema validator but I fear it will be too complicated, or otherwise the types will be too broad (which can be good enough…).
thank you @lud for your great libray as well!
It was not that hard but quite tedious since Zoi supports many types. A few examples:
Zoi.string/1 is simply binary() under the hood, check here.Zoi.union/2 loops through the list of schemas and add the | operator, check hereZoi.object/2, one of the most complex types, is a basic loop that calls the type_spec function recursively, here.So if you build a map like this (map where the value is a list of integers):
@schema Zoi.object(%{numbers: Zoi.array(Zoi.integer())})
@type schema :: unquote(Zoi.type_spec(@schema))
The type would have the following AST:
{:%{}, [], [{{:required, [], [:numbers]}, [{:integer, [], []}]}]}
which translates to:
%{numbers: [integer()]}
So quite precise in terms of how the type should be according to your schema
It’s good that you have a struct for each type, so you can directly map the struct to a typespec in many cases.
I’ll have to infer a lot more things, but I can take some inspiration from your code ![]()
Thank you!