{"id":18386805,"url":"https://github.com/erlangsters/term-validator","last_synced_at":"2025-04-12T02:11:20.096Z","repository":{"id":166426235,"uuid":"620882016","full_name":"erlangsters/term-validator","owner":"erlangsters","description":"A quick and simple Erlang term validator.","archived":false,"fork":false,"pushed_at":"2024-09-24T17:24:24.000Z","size":168,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-02-16T00:26:13.825Z","etag":null,"topics":["erlang","format","schema","specs","term","validator"],"latest_commit_sha":null,"homepage":"https://www.erlangsters.org/","language":"Erlang","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/erlangsters.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-03-29T14:54:35.000Z","updated_at":"2024-09-24T17:24:27.000Z","dependencies_parsed_at":null,"dependency_job_id":"bfd6fdc3-e33f-447b-8615-a59f4c096ade","html_url":"https://github.com/erlangsters/term-validator","commit_stats":null,"previous_names":["erlangsters/term-validator"],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/erlangsters%2Fterm-validator","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/erlangsters%2Fterm-validator/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/erlangsters%2Fterm-validator/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/erlangsters%2Fterm-validator/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/erlangsters","download_url":"https://codeload.github.com/erlangsters/term-validator/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248505928,"owners_count":21115354,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["erlang","format","schema","specs","term","validator"],"created_at":"2024-11-06T01:23:28.928Z","updated_at":"2025-04-12T02:11:20.073Z","avatar_url":"https://github.com/erlangsters.png","language":"Erlang","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Term Validator\n\nA quick and simple Erlang term validator. It supports validation of the common\nbuilt-in Erlang types and can be extended with custom validators.\n\n```erlang\nFormat = {number, [{min, 10}]}.\n\nvalid = term_validator:validate(42, Format).\n{invalid, not_number} = term_validator:validate(\"Hello world!\", Format).\n```\n\nThe documentation is entirely self-contained in the\n[DOCUMENTATION.md](/DOCUMENTATION.md) file in the root of the project folder.\nYou may also want to check the regression suites in the *test* folder for more\nexamples.\n\n\u003e If you need to validate settings/config files or JSON data, check\n\u003e out the [Settings Validator](https://github.com/erlangsters/settings-validator)\n\u003e and [JSON Validator](https://github.com/erlangsters/json-validator) projects.\n\nWritten by Jonathan De Wachter (dewachter.jonathan@gmail.com) and released\nunder the MIT license.\n\n## Getting started\n\nThe `term_validator` module features a single `validate/2` function that takes\nan Erlang term and its expected format, then returns `valid` or\n`{invalid, Reason}`.\n\nA **term format** is a tuple with the first element being the validator name,\nand the second element being a list of options to be passed to the underlying\nvalidate functions. If no options are needed, the format can simply be the\nvalidator name.\n\nFor instance, those two term formats are equivalent.\n\n```erlang\nvalid = term_validator:validate(42, number).\nvalid = term_validator:validate(42, {number, []}).\n```\n\nTypes such as list, tuples and maps can nest other types. This is why their\nvalidators take other term formats as options (in order to validate the\nnested types).\n\nFor instance, the following format validates any list with at least two numbers\nthat are all greater than or equal to 10.\n\n```erlang\nFormat = {list, [\n    {item, {number, [{min, 10}]}},\n    {min, 2}\n]}.\n\n{invalid, not_list} =\n  term_validator:validate(42, Format).\n{invalid, {length, {must_be_greater_or_equal, 2}}} =\n  term_validator:validate([42], Format).\n{invalid, {items, [{1, not_number}]}} =\n  term_validator:validate([zero, 42], Format).\n{invalid, {items, [{1, {value, {must_be_greater_or_equal, 10}}}]}} =\n  term_validator:validate([0, 42], Format).\n\nvalid = term_validator:validate([24, 42], Format).\n```\n\n(Notice that the `{number, [{min, 10}]}` is the format of the nested type.)\n\nBy default, the validate function uses a list of built-in validators (which\nthis project has already implemented for you) but you may extend (or replace)\nthis list with your custom validators.\n\nSuppose you have implemented the `foo` validator in the `my_foo_validator`\nmodule, then you can pass it to the validate function as follows.\n\n```erlang\nFormat = {list, [{item, foo}]},\nValidators = maps:merge(term_validator:validators(), #{foo =\u003e my_foo_validator}),\nvalid = term_validator:validate([foo, foo, foo], Format, Validators),\n\n% If you do not add your custom validator, it's reported.\n{no_validator, foo} = term_validator:validate([foo, foo, foo], Format),\n```\n\nWith that example being shown, in practice you hardly ever need to create\ncustom validators as most complex validation rules be created with a\ncombination of the built-in validators.\n\nRefer to the list of built-in validators to understand how to write your term\nformat. You will find a quick [table](#the-built-in-validators) below but\nthey're extensively explained in the [documentation](/DOCUMENTATION.md).\n\n## Using it in your project\n\nWith the **Rebar3** build system, add the following to the `rebar.config` file\nof your project.\n\n```\n{deps, [\n  {term_validator, {git, \"https://github.com/erlangsters/term-validator.git\", {tag, \"master\"}}}\n]}.\n```\n\nIf you happen to use the **Erlang.mk** build system, then add the following to\nyour Makefile.\n\n```\nBUILD_DEPS = term_validator\ndep_term_validator = git https://github.com/erlangsters/term-validator master\n```\n\nIn practice, you want to replace the branch \"master\" with a specific \"tag\" to\navoid breaking your project if incompatible changes are made.\n\n## The built-in validators\n\nThe need for validating values is often encountered when dealing with external\ninput that uses the basic data structures such as strings, numbers or booleans,\nand sometimes nested data structures such as lists, tuples or maps. In fact,\nthose input are not always Erlang terms directly but instead are converted to\nErlang terms from another format such as JSON. This is why this library does\nnot support all built-in Erlang types but only the common ones. However, you\ncan easily extend it with your own validators.\n\nHere is the list of the built-in validators with their options.\n\n| Validator       | Options                                                                  |\n| --------------- | ------------------------------------------------------------------------ |\n| `any`           | *No options.*                                                            |\n| `atom`          | `one_of`, `allow_string`                                                 |\n| `bool`          | `allow_number`                                                           |\n| `number`        | `min`, `max`, `integer_only`, `multiple_of`                              |\n| `string`        | `length`, `min`\\*, `max`\\*, `alphabet`, `pattern`, `ascii`\\*, `latin1`\\* |\n| `list`          | `item`, `length`, `min`\\*, `max`\\*                                       |\n| `tuple`         | `elements`                                                               |\n| `tuple_dynamic` | `element`, `length`, `min`\\*, `max`\\*                                    |\n| `map`           | `fields`                                                                 |\n| `map_dynamic`   | `key`, `value`, `length`, `min`\\*, `max`\\*                               |\n| `any_of`        | *Any term format.* **                                                    |\n| `all_of`        | *Any term format.* **                                                    |\n\n*Shortcut options; they cannot be used with the `length` option.  \n**Instead of being a list of options, it's a list of term format.\n\nThe `any` validator will validate any Erlang term (useful in some scenarios).\n\nIf you're interested in validators for more complex types such as IPs, ports,\ndates, colors, etc, you may want to check out the Extended Term Validator\nrepository (https://github.com/erlangsters/extended-term-validator).\n\n## Writing a new validator\n\nA validator is a module that implements a set of validate functions and defines\na list of options it supports.\n\nA concrete example will speak louder than words.\n\n```erlang\n-module(my_validator).\n\n-export([options/1]).\n-export([pre_validate/3, validate/3, post_validate/2]).\n\noptions(mandatory) -\u003e [foo];\noptions(optional) -\u003e [bar, quz].\n\npre_validate(Term, Options, _Validators) -\u003e {valid, Term, Options}.\n\nvalidate(Term, {foo, _Value}, _Validators) -\u003e {valid, Term}.\nvalidate(Term, {bar, _Value}, _Validators) -\u003e {valid, Term}.\nvalidate(Term, {quz, _Value}, _Validators) -\u003e {valid, Term}.\n\npost_validate(Term, _Validators) -\u003e valid.\n```\n\nIt uses a function chaining technique to let you implement complex validation\nrules easily. To understand how to implement custom validator in depth, refer\nto the documentation.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ferlangsters%2Fterm-validator","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ferlangsters%2Fterm-validator","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ferlangsters%2Fterm-validator/lists"}