{"id":18834279,"url":"https://github.com/chubbyphp/chubbyphp-parsing","last_synced_at":"2025-04-14T04:32:21.894Z","repository":{"id":215500257,"uuid":"738676931","full_name":"chubbyphp/chubbyphp-parsing","owner":"chubbyphp","description":"Allows parsing data of various structures, meaning the population and validation of data into a defined structure. For example, converting an API request into a Data Transfer Object (DTO).","archived":false,"fork":false,"pushed_at":"2025-03-12T13:51:35.000Z","size":268,"stargazers_count":14,"open_issues_count":1,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-27T18:55:26.351Z","etag":null,"topics":["chubbyphp","dto","parsing","population","validation","zod"],"latest_commit_sha":null,"homepage":"","language":"PHP","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/chubbyphp.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,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-01-03T19:33:01.000Z","updated_at":"2025-03-26T19:43:15.000Z","dependencies_parsed_at":"2024-01-22T23:25:19.202Z","dependency_job_id":"3ec2b3d4-1df1-4614-a6e4-23751086476c","html_url":"https://github.com/chubbyphp/chubbyphp-parsing","commit_stats":{"total_commits":86,"total_committers":1,"mean_commits":86.0,"dds":0.0,"last_synced_commit":"447bc34ce64ab9e4f653b13dfa84a9ceb0a33caa"},"previous_names":["chubbyphp/chubbyphp-parsing"],"tags_count":7,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chubbyphp%2Fchubbyphp-parsing","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chubbyphp%2Fchubbyphp-parsing/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chubbyphp%2Fchubbyphp-parsing/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chubbyphp%2Fchubbyphp-parsing/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/chubbyphp","download_url":"https://codeload.github.com/chubbyphp/chubbyphp-parsing/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248821979,"owners_count":21166985,"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":["chubbyphp","dto","parsing","population","validation","zod"],"created_at":"2024-11-08T02:11:39.597Z","updated_at":"2025-04-14T04:32:21.887Z","avatar_url":"https://github.com/chubbyphp.png","language":"PHP","readme":"# chubbyphp-parsing\n\n[![CI](https://github.com/chubbyphp/chubbyphp-parsing/actions/workflows/ci.yml/badge.svg)](https://github.com/chubbyphp/chubbyphp-parsing/actions/workflows/ci.yml)\n[![Coverage Status](https://coveralls.io/repos/github/chubbyphp/chubbyphp-parsing/badge.svg?branch=master)](https://coveralls.io/github/chubbyphp/chubbyphp-parsing?branch=master)\n[![Mutation testing badge](https://img.shields.io/endpoint?style=flat\u0026url=https%3A%2F%2Fbadge-api.stryker-mutator.io%2Fgithub.com%2Fchubbyphp%2Fchubbyphp-parsing%2Fmaster)](https://dashboard.stryker-mutator.io/reports/github.com/chubbyphp/chubbyphp-parsing/master)\n[![Latest Stable Version](https://poser.pugx.org/chubbyphp/chubbyphp-parsing/v)](https://packagist.org/packages/chubbyphp/chubbyphp-parsing)\n[![Total Downloads](https://poser.pugx.org/chubbyphp/chubbyphp-parsing/downloads)](https://packagist.org/packages/chubbyphp/chubbyphp-parsing)\n[![Monthly Downloads](https://poser.pugx.org/chubbyphp/chubbyphp-parsing/d/monthly)](https://packagist.org/packages/chubbyphp/chubbyphp-parsing)\n\n[![bugs](https://sonarcloud.io/api/project_badges/measure?project=chubbyphp_chubbyphp-parsing\u0026metric=bugs)](https://sonarcloud.io/dashboard?id=chubbyphp_chubbyphp-parsing)\n[![code_smells](https://sonarcloud.io/api/project_badges/measure?project=chubbyphp_chubbyphp-parsing\u0026metric=code_smells)](https://sonarcloud.io/dashboard?id=chubbyphp_chubbyphp-parsing)\n[![coverage](https://sonarcloud.io/api/project_badges/measure?project=chubbyphp_chubbyphp-parsing\u0026metric=coverage)](https://sonarcloud.io/dashboard?id=chubbyphp_chubbyphp-parsing)\n[![duplicated_lines_density](https://sonarcloud.io/api/project_badges/measure?project=chubbyphp_chubbyphp-parsing\u0026metric=duplicated_lines_density)](https://sonarcloud.io/dashboard?id=chubbyphp_chubbyphp-parsing)\n[![ncloc](https://sonarcloud.io/api/project_badges/measure?project=chubbyphp_chubbyphp-parsing\u0026metric=ncloc)](https://sonarcloud.io/dashboard?id=chubbyphp_chubbyphp-parsing)\n[![sqale_rating](https://sonarcloud.io/api/project_badges/measure?project=chubbyphp_chubbyphp-parsing\u0026metric=sqale_rating)](https://sonarcloud.io/dashboard?id=chubbyphp_chubbyphp-parsing)\n[![alert_status](https://sonarcloud.io/api/project_badges/measure?project=chubbyphp_chubbyphp-parsing\u0026metric=alert_status)](https://sonarcloud.io/dashboard?id=chubbyphp_chubbyphp-parsing)\n[![reliability_rating](https://sonarcloud.io/api/project_badges/measure?project=chubbyphp_chubbyphp-parsing\u0026metric=reliability_rating)](https://sonarcloud.io/dashboard?id=chubbyphp_chubbyphp-parsing)\n[![security_rating](https://sonarcloud.io/api/project_badges/measure?project=chubbyphp_chubbyphp-parsing\u0026metric=security_rating)](https://sonarcloud.io/dashboard?id=chubbyphp_chubbyphp-parsing)\n[![sqale_index](https://sonarcloud.io/api/project_badges/measure?project=chubbyphp_chubbyphp-parsing\u0026metric=sqale_index)](https://sonarcloud.io/dashboard?id=chubbyphp_chubbyphp-parsing)\n[![vulnerabilities](https://sonarcloud.io/api/project_badges/measure?project=chubbyphp_chubbyphp-parsing\u0026metric=vulnerabilities)](https://sonarcloud.io/dashboard?id=chubbyphp_chubbyphp-parsing)\n\n\n## Description\n\nAllows parsing data of various structures, meaning the population and validation of data into a defined structure. For example, converting an API request into a Data Transfer Object (DTO).\n\nHeavily inspired by the well-known TypeScript library [zod](https://github.com/colinhacks/zod).\n\n## Requirements\n\n * php: ^8.2\n\n## Installation\n\nThrough [Composer](http://getcomposer.org) as [chubbyphp/chubbyphp-parsing][1].\n\n```sh\ncomposer require chubbyphp/chubbyphp-parsing \"^1.3\"\n```\n\n## Usage\n\n```php\nuse Chubbyphp\\Parsing\\Schema\\SchemaInterface;\n\n/** @var SchemaInterface $schema */\n$schema = ...;\n\n$schema-\u003enullable();\n$schema-\u003epreParse(static fn ($input) =\u003e $input);\n$schema-\u003epostParse(static fn (string $output) =\u003e $output);\n$schema-\u003eparse('test');\n$schema-\u003esafeParse('test');\n$schema-\u003ecatch(static fn (string $output, ParserErrorException $e) =\u003e $output);\n```\n\n### array\n\n```php\nuse Chubbyphp\\Parsing\\Parser;\n\n$p = new Parser();\n\n$schema = $p-\u003earray($p-\u003eint());\n\n$data = $schema-\u003eparse([1, 2, 3, 4, 5]);\n\n// validations\n$schema-\u003elength(5);\n$schema-\u003eminLength(5);\n$schema-\u003emaxLength(5);\n$schema-\u003eincludes(5);\n\n// transformations\n$schema-\u003efilter(static fn (int $value) =\u003e 0 === $value % 2);\n$schema-\u003emap(static fn (int $value) =\u003e $value * 2);\n$schema-\u003esort();\n$schema-\u003esort(static fn (int $a, int $b) =\u003e $b - $a);\n\n// conversions\n$schema-\u003ereduce(static fn (int $sum, int $current) =\u003e $sum + $current, 0);\n```\n\n### backedEnum\n\n```php\nuse Chubbyphp\\Parsing\\Parser;\n\nenum BackedSuit: string\n{\n    case Hearts = 'H';\n    case Diamonds = 'D';\n    case Clubs = 'C';\n    case Spades = 'S';\n}\n\n$p = new Parser();\n\n$schema = $p-\u003ebackedEnum(BackedSuit::class);\n\n$data = $schema-\u003eparse('D');\n\n// validations\n\n// transformations\n\n// conversions\n$schema-\u003etoInt();\n$schema-\u003etoString();\n```\n\n### bool\n\n```php\nuse Chubbyphp\\Parsing\\Parser;\n\n$p = new Parser();\n\n$schema = $p-\u003ebool();\n\n$data = $schema-\u003eparse(true);\n\n// validations\n\n// transformations\n\n// conversions\n$schema-\u003etoInt();\n$schema-\u003etoString();\n```\n\n### dateTime\n\n```php\nuse Chubbyphp\\Parsing\\Parser;\n\n$p = new Parser();\n\n$schema = $p-\u003edateTime();\n\n$data = $schema-\u003eparse(new \\DateTimeImmutable('2024-01-20T09:15:00+00:00'));\n\n// validations\n$schema-\u003efrom(new \\DateTimeImmutable('2024-01-20T09:15:00+00:00'));\n$schema-\u003eto(new \\DateTimeImmutable('2024-01-20T09:15:00+00:00'));\n\n// transformations\n\n// conversions\n$schema-\u003etoInt();\n$schema-\u003etoString();\n```\n\n### discriminatedUnion\n\n```php\nuse Chubbyphp\\Parsing\\Parser;\n\n$p = new Parser();\n\n$schema = $p-\u003ediscriminatedUnion([\n    $p-\u003eobject(['_type' =\u003e $p-\u003eliteral('email'), 'address' =\u003e $p-\u003estring()]),\n    $p-\u003eobject(['_type' =\u003e $p-\u003eliteral('phone'), 'number' =\u003e $p-\u003estring()]),\n]);\n\n$data = $schema-\u003eparse(['_type' =\u003e 'phone', 'number' =\u003e '+41790000000']);\n```\n\n### float\n\n```php\nuse Chubbyphp\\Parsing\\Parser;\n\n$p = new Parser();\n\n$schema = $p-\u003efloat();\n\n$data = $schema-\u003eparse(4.2);\n\n// validations\n$schema-\u003egt(5.0);\n$schema-\u003egte(5.0);\n$schema-\u003elt(5.0);\n$schema-\u003elte(5.0);\n$schema-\u003epositive();\n$schema-\u003enonNegative();\n$schema-\u003enegative();\n$schema-\u003enonPositive();\n\n// transformations\n\n// conversions\n$schema-\u003etoInt();\n$schema-\u003etoString();\n```\n\n### int\n\n```php\nuse Chubbyphp\\Parsing\\Parser;\n\n$p = new Parser();\n\n$schema = $p-\u003eint();\n\n$data = $schema-\u003eparse(1337);\n\n// validations\n$schema-\u003egt(5);\n$schema-\u003egte(5);\n$schema-\u003elt(5);\n$schema-\u003elte(5);\n$schema-\u003epositive();\n$schema-\u003enonNegative();\n$schema-\u003enegative();\n$schema-\u003enonPositive();\n\n// transformations\n\n// conversions\n$schema-\u003etoDateTime();\n$schema-\u003etoFloat();\n$schema-\u003etoString();\n```\n\n### lazy\n\n```php\nuse Chubbyphp\\Parsing\\Parser;\n\n$p = new Parser();\n\n$schema = $p-\u003elazy(static function () use ($p, \u0026$schema) {\n    return $p-\u003eobject([\n        'name' =\u003e $p-\u003estring(),\n        'child' =\u003e $schema,\n    ])-\u003enullable();\n});\n\n$data = $schema-\u003eparse([\n    'name' =\u003e 'name1',\n    'child' =\u003e [\n        'name' =\u003e 'name2',\n        'child' =\u003e null\n    ],\n]);\n```\n\n### literal\n\n```php\nuse Chubbyphp\\Parsing\\Parser;\n\n$p = new Parser();\n\n$schema = $p-\u003eliteral('email'); // supports string|float|int|bool\n\n$data = $schema-\u003eparse('email');\n```\n\n### object\n\n```php\nuse Chubbyphp\\Parsing\\Parser;\n\n$p = new Parser();\n\n$schema = $p-\u003eobject(['name' =\u003e $p-\u003estring()]);\n\n// stdClass object\n$data = $schema-\u003eparse(['name' =\u003e 'example']);\n\n// SampleClass object\n$data = $schema-\u003eparse(['name' =\u003e 'example'], SampleNamespace\\SampleClass::class);\n\n// if the key 'name' does not exist on input, it won't exists on the output\n$schema-\u003eoptional(['name']);\n\n// validations\n$schema-\u003estrict();\n$schema-\u003estrict(['_id']); // strip _id if given, but complain about any other additional field\n\n// transformations\n\n// conversions\n```\n\n### record\n\n```php\nuse Chubbyphp\\Parsing\\Parser;\n\n$p = new Parser();\n\n$schema = $p-\u003erecord($p-\u003estring());\n\n$data = $schema-\u003eparse([\n    'key1' =\u003e 'value1',\n    'key2' =\u003e 'value2'\n]);\n```\n\n### respectValidation\n\n```sh\ncomposer require respect/validation \"^2.4\"\n```\n\n```php\nuse Chubbyphp\\Parsing\\Parser;\nuse Respect\\Validation\\Validator as v;\n\n$p = new Parser();\n\n$schema = $p-\u003erespectValidation(v::numericVal()-\u003epositive()-\u003ebetween(1, 255));\n\n$data = $schema-\u003eparse(5);\n```\n\n### string\n\n```php\nuse Chubbyphp\\Parsing\\Parser;\n\n$p = new Parser();\n\n$schema = $p-\u003estring();\n\n$data = $schema-\u003eparse('example');\n\n// validations\n$schema-\u003elength(5);\n$schema-\u003eminLength(5);\n$schema-\u003emaxLength(5);\n$schema-\u003eincludes('amp');\n$schema-\u003estartsWith('exa');\n$schema-\u003eendsWith('mpl');\n$schema-\u003ematch('/^[a-z]+$/i');\n$schema-\u003eemail();\n$schema-\u003eipV4();\n$schema-\u003eipV6();\n$schema-\u003eurl();\n$schema-\u003euuidV4();\n$schema-\u003euuidV5();\n\n// transformations\n$schema-\u003etrim();\n$schema-\u003etrimStart();\n$schema-\u003etrimEnd();\n$schema-\u003etoLowerCase();\n$schema-\u003etoUpperCase();\n\n// conversions\n$schema-\u003etoDateTime();\n$schema-\u003etoFloat();\n$schema-\u003etoInt();\n\n// examples\n$notBlankSchema = $schema-\u003etrim()-\u003eminSize(1);\n```\n\n### tuple\n\n```php\nuse Chubbyphp\\Parsing\\Parser;\n\n$p = new Parser();\n\n$schema = $p-\u003etuple([$p-\u003efloat(), $p-\u003efloat()]);\n\n$data = $schema-\u003eparse([47.1, 8.2]);\n```\n\n### union\n\n```php\nuse Chubbyphp\\Parsing\\Parser;\n\n$p = new Parser();\n\n$schema = $p-\u003eunion([$p-\u003estring(), $p-\u003eint()]);\n\n$data = $schema-\u003eparse('42');\n```\n\n## Copyright\n\n2025 Dominik Zogg\n\n[1]: https://packagist.org/packages/chubbyphp/chubbyphp-parsing\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchubbyphp%2Fchubbyphp-parsing","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fchubbyphp%2Fchubbyphp-parsing","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchubbyphp%2Fchubbyphp-parsing/lists"}