{"id":15056421,"url":"https://github.com/bottleneko/dtrans","last_synced_at":"2025-04-10T04:10:24.545Z","repository":{"id":57491902,"uuid":"162621224","full_name":"bottleneko/dtrans","owner":"bottleneko","description":"Erlang data-transformation and validation micro library","archived":false,"fork":false,"pushed_at":"2018-12-30T14:53:36.000Z","size":40,"stargazers_count":4,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-03-24T05:25:59.728Z","etag":null,"topics":["data-transformation","erlang","not-production-ready","validation"],"latest_commit_sha":null,"homepage":"","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/bottleneko.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-12-20T19:09:14.000Z","updated_at":"2019-01-07T07:00:14.000Z","dependencies_parsed_at":"2022-08-28T11:23:37.991Z","dependency_job_id":null,"html_url":"https://github.com/bottleneko/dtrans","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bottleneko%2Fdtrans","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bottleneko%2Fdtrans/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bottleneko%2Fdtrans/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bottleneko%2Fdtrans/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bottleneko","download_url":"https://codeload.github.com/bottleneko/dtrans/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248154986,"owners_count":21056543,"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":["data-transformation","erlang","not-production-ready","validation"],"created_at":"2024-09-24T21:51:09.758Z","updated_at":"2025-04-10T04:10:24.520Z","avatar_url":"https://github.com/bottleneko.png","language":"Erlang","funding_links":[],"categories":[],"sub_categories":[],"readme":"dtrans [![Build Status](https://travis-ci.org/bottleneko/dtrans.svg?branch=master)](https://travis-ci.org/bottleneko/dtrans)\n=====\n\nData transformation and validation micro library. Not production ready.\n Breaking changes is coming\n\nTake a wow-effect from coverage\n-----\n\n```sh\n$ rebar3 ct --cover \u0026\u0026 rebar3 cover --verbose\n```\n\n# Short documentation \n\n## Field properties\n\n### Internal\n\nAssociation `internal =\u003e true` means that this field be constructed \nwithout input data using only functions with /0 arity and other \nfrom fields values throught tuple:\n\n`{depends_on, [other_field_name], fun(OtherFieldValue) -\u003e {ok, 42} end}`\n\n\u003e Note: lambda-function above will be called with validated and constructed values \n\n\u003e Warning: when this property is set as `true` - `required`, `validator`, `default_value` being ignored\n\n```erlang\n1\u003e {ok, Model} = dtrans:new(#{\n      timestamp =\u003e\n        #{internal =\u003e true,\n          constructor =\u003e \n            fun() -\u003e \n                {ok, erlang:apply(erlang, timestamp, [])} \n            end\n        }\n    }).\n2\u003e dtrans:extract(#{}, Model).\n{ok,#{timestamp =\u003e {1545,494367,679728}}}\n```\n\n\u003e Note: default value of this property is `false`\n\n### Required\n\nCorrectly set `required` field give the opportunity checks model \nwhile building in future this will be used in compile-time models\n checks \n\n```erlang\n1\u003e dtrans:new(#{\n      a =\u003e\n        #{required      =\u003e false,\n          default_value =\u003e 0\n        },\n      b =\u003e \n        #{required      =\u003e false,\n          default_value =\u003e 0\n        },\n      sum_of_a_and_b =\u003e\n        #{internal    =\u003e true,\n          required    =\u003e true,\n          constructor =\u003e \n            {depends_on, \n              [a, b], \n              fun(A, B) -\u003e {ok, A + B} end}\n        }\n    }).\n{error,dependency_tree_model_cannot_be_resolved}\n```\n\nAnd this field property using while data extracting\n\n```erlang\n1\u003e {ok, Model} = dtrans:new(#{\n      required_field =\u003e\n        #{required =\u003e true}\n    }).\n2\u003e dtrans:extract(#{}, Model).\n{error,{no_data,required_field}}\n```\n\n\u003e Note: default value of this property is `false`\n    \n### Validator\n\nThis field may be set validation lambda-function with /1 arity.\nThis function should be return `ok` or `{error, Reason :: any()}` values \n\n```erlang\n1\u003e {ok, Model} = dtrans:new(#{\n      invalid_field =\u003e\n        #{validator =\u003e\n            fun\n                (42 = _Value) -\u003e ok;\n                (_Value)      -\u003e  {error, \"Expected value is 42\"}\n            end\n        }\n    }).\n2\u003e dtrans:extract(#{invalid_field =\u003e 43}, Model).\n{error,{validation_error,invalid_field,\"Expected value is 42\"}}\n```\n\n\u003e Note: default value of this property is constant `ok`\n  \n### Default value\n\nDefault value working only for `required =\u003e false` not internal fields\n\n```erlang\n1\u003e {ok, Model} = dtrans:new(#{\n      field =\u003e\n        #{default_value =\u003e 0}\n    }).\n2\u003e dtrans:extract(#{}, Model).\n{ok,#{field =\u003e 0}}\n3\u003e dtrans:extract(#{field =\u003e 42}, Model).\n{ok,#{field =\u003e 42}}\n```\n\n```erlang\n1\u003e {ok, Model} = dtrans:new(#{\n      field =\u003e #{}\n    }).\n2\u003e dtrans:extract(#{}, Model).\n{ok,#{}}\n3\u003e dtrans:extract(#{field =\u003e 42}, Model).\n{ok,#{field =\u003e 42}}\n```\n\n## Constructor\n\nYou can change final value of field throught set property `constructor` by lambda function with /1 arity \nor tuple for using other fields values:\n\n`{depends_on, [other_field_name], fun(MainFieldValue, OtherFieldValue) -\u003e {ok, 42} end}`\n\nConstruction functions must be returns `{ok, Value :: any()}` or `{error, Reason :: any()}` values\n\n\u003e Note: lambda-function above will be called with validated and constructed values \n\n\u003e Warning: by using `depends_on` you may be show `{error, {cyclic_dependency, [...]} while building model`\n\n```erlang\n1\u003e {ok, Model} = dtrans:new(#{\n      field =\u003e\n        #{constructor =\u003e \n            fun(Value) -\u003e \n              {ok, Value + 41}\n            end\n         }\n    }).\n2\u003e dtrans:extract(#{field =\u003e 1}, Model).\n{ok,#{field =\u003e 42}}\n```\n\n\u003e Note: default value of this property is identity function\n\n### Model\n\nWith `model` property you can inherit model in other model as field specification\n\n```erlang\n1\u003e {ok, InnerModel} = dtrans:new(#{\n      inner_field =\u003e #{}\n    }).\n2\u003e {ok, OuterModel} = dtrans:new(#{\n      outer_field =\u003e \n        #{required =\u003e true,\n          model    =\u003e InnerModel\n         }\n    }).\n3\u003e dtrans:extract(#{outer_field =\u003e #{inner_field =\u003e 4}}, OuterModel).\n{ok, #{outer_field =\u003e #{inner_field =\u003e 4}}}\n```\n\n### Count\n\nWhile `count` property is set to `one` lists will be processing as one \nobject, while is set to `many` lists processiong as list of models and\n validation/extraction will be called on each element\n \n ```erlang\n1\u003e {ok, Model} = dtrans:new(#{\n      field =\u003e \n        #{count       =\u003e many,\n          constructor =\u003e fun(Value) -\u003e {ok, Value + 1} end\n         }\n    })\n2\u003e dtrans:extract(#{field =\u003e [1, 2, 3]}, Model).\n{ok,#{field =\u003e [2,3,4]}}\n```\n\n\u003e Note: default value of this property is `one`\n\n# TODO\n\n* [ ] Add compile-time build for models where possible\n* [ ] Add more information to errors\n* [x] Use other model as field spec\n    * [x] New model field property `model`\n    * [x] New model field property set count of models ","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbottleneko%2Fdtrans","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbottleneko%2Fdtrans","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbottleneko%2Fdtrans/lists"}