{"id":22235318,"url":"https://github.com/williamthome/changeset","last_synced_at":"2025-07-27T21:32:44.245Z","repository":{"id":166713499,"uuid":"642226467","full_name":"williamthome/changeset","owner":"williamthome","description":"An OTP library to validate data based on Ecto changeset library (Elixir).","archived":false,"fork":false,"pushed_at":"2023-10-13T22:01:08.000Z","size":112,"stargazers_count":3,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2024-05-01T17:21:39.697Z","etag":null,"topics":["changeset","erlang","erlang-library","rebar3","validate","validation-library"],"latest_commit_sha":null,"homepage":"","language":"Erlang","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/williamthome.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null},"funding":{"github":["williamthome"],"patreon":null,"open_collective":null,"ko_fi":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"otechie":null,"lfx_crowdfunding":null,"custom":["https://www.buymeacoffee.com/williamthome"]}},"created_at":"2023-05-18T05:16:17.000Z","updated_at":"2024-02-23T07:25:20.000Z","dependencies_parsed_at":"2023-10-14T22:45:31.296Z","dependency_job_id":null,"html_url":"https://github.com/williamthome/changeset","commit_stats":null,"previous_names":["williamthome/changeset"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/williamthome%2Fchangeset","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/williamthome%2Fchangeset/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/williamthome%2Fchangeset/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/williamthome%2Fchangeset/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/williamthome","download_url":"https://codeload.github.com/williamthome/changeset/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":227836979,"owners_count":17827066,"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":["changeset","erlang","erlang-library","rebar3","validate","validation-library"],"created_at":"2024-12-03T02:12:48.649Z","updated_at":"2024-12-03T02:12:49.426Z","avatar_url":"https://github.com/williamthome.png","language":"Erlang","readme":"# changeset\n\nAn OTP library to validate data based on Ecto changeset library (Elixir).\n\n## Disclaimer\n\nThis is a WIP library. The code may change at any time without notice.\n\n## Example\n\nTake this simple module:\n\n```erlang\n-module(movie).\n\n-export([changeset/1, changeset/2]).\n\n-define(TYPES,     #{name =\u003e binary, starring =\u003e binary}).\n-define(PERMITTED, maps:keys(?TYPES)).\n-define(REQUIRED,  [name]).\n\nchangeset(Params) -\u003e\n    changeset(#{}, Params).\n\nchangeset(Data, Params) -\u003e\n    Changeset = changeset:cast({Data, ?TYPES}, Params, ?PERMITTED),\n    changeset:pipe(Changeset, [\n        changeset:validate_required(?REQUIRED)\n        % More validators here, e.g.:\n        % changeset:validate_change(name, fun(_Name) -\u003e [] end)\n        % changeset:validate_format(name, \"^[A-Z]\")\n        % changeset:validate_member(starring, [\u003c\u003c\"Mike\"\u003e\u003e, \u003c\u003c\"Joe\"\u003e\u003e, \u003c\u003c\"Robert\"\u003e\u003e])\n        % changeset:validate_not_member(starring, [\u003c\u003c\"Me\"\u003e])\n    ]).\n```\n\nNow running\n\n```shell\nrebar3 shell\n```\n\nwe can type the following:\n\n```erlang\n% The name is missing, the changeset will be invalid\n1\u003e movie:changeset(#{}).\n{changeset,[],\n           #{name =\u003e binary,starring =\u003e binary},\n           [name],\n           #{},#{},\n           [{name,{\u003c\u003c\"is required\"\u003e\u003e,#{validation =\u003e is_required}}}],\n           [undefined,\u003c\u003c\u003e\u003e]}\n\n% The name is not a binary, the changeset will be invalid\n2\u003e movie:changeset(#{name =\u003e foo}).\n{changeset,[],\n           #{name =\u003e binary,starring =\u003e binary},\n           [name],\n           #{},\n           #{name =\u003e foo},\n           [{name,{\u003c\u003c\"must be a binary\"\u003e\u003e,#{validation =\u003e is_binary}}}],\n           [undefined,\u003c\u003c\u003e\u003e]}\n\n% The name is present and it's a binary, then the changeset will be valid\n3\u003e movie:changeset(#{name =\u003e \u003c\u003c\"Erlang: The Movie\"\u003e\u003e}).\n{changeset,[],\n           #{name =\u003e binary,starring =\u003e binary},\n           [name],\n           #{},\n           #{name =\u003e \u003c\u003c\"Erlang: The Movie\"\u003e\u003e},\n           [],\n           [undefined,\u003c\u003c\u003e\u003e]}\n\n% Get the valid changes\n4\u003e changeset:get_changes(v(3)).\n#{name =\u003e \u003c\u003c\"Erlang: The Movie\"\u003e\u003e}\n```\n\n## Struct\n\nCurrently, this is the changeset record\n\n```erlang\n-record(changeset,\n    { fields       = []                :: [field()]\n    , types        = #{}               :: #{field() := type()}\n    , required     = []                :: [field()]\n    , data         = #{}               :: #{field() =\u003e term()}\n    , changes      = #{}               :: #{field() =\u003e term()}\n    , errors       = []                :: [error()]\n    , empty_values = [undefined, \u003c\u003c\u003e\u003e] :: nonempty_list()\n    }).\n```\n\nand this are the available field types:\n\n```erlang\n-type type() :: atom\n              | binary\n              | bitstring\n              | boolean\n              | float\n              | function\n              | {function, arity()}\n              | integer\n              | list\n              | map\n              | pid\n              | port\n              | record\n              | {record, Name :: atom()}\n              | {record, Name :: atom(), Size :: non_neg_integer()}\n              | reference\n              | tuple\n              .\n```\n\nThe types are auto validated by the cast function.\n","funding_links":["https://github.com/sponsors/williamthome","https://www.buymeacoffee.com/williamthome"],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwilliamthome%2Fchangeset","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwilliamthome%2Fchangeset","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwilliamthome%2Fchangeset/lists"}