Skip to content

Latest commit

 

History

History
387 lines (266 loc) · 9.1 KB

README.md

File metadata and controls

387 lines (266 loc) · 9.1 KB

chubbyphp-parsing

CI Coverage Status Mutation testing badge Latest Stable Version Total Downloads Monthly Downloads

bugs code_smells coverage duplicated_lines_density ncloc sqale_rating alert_status reliability_rating security_rating sqale_index vulnerabilities

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).

Heavily inspired by the well-known TypeScript library zod.

Requirements

  • php: ^8.1

Installation

Through Composer as chubbyphp/chubbyphp-parsing.

composer require chubbyphp/chubbyphp-parsing "^1.2"

Usage

use Chubbyphp\Parsing\Schema\SchemaInterface;

/** @var SchemaInterface $schema */
$schema = ...;

$schema->nullable();
$schema->preParse(static fn ($input) => $input);
$schema->postParse(static fn (string $output) => $output);
$schema->parse('test');
$schema->safeParse('test');
$schema->catch(static fn (string $output, ParserErrorException $e) => $output);

array

use Chubbyphp\Parsing\Parser;

$p = new Parser();

$schema = $p->array($p->int());

$data = $schema->parse([1, 2, 3, 4, 5]);

// validations
$schema->length(5);
$schema->minLength(5);
$schema->maxLength(5);
$schema->includes(5);

// transformations
$schema->filter(static fn (int $value) => 0 === $value % 2);
$schema->map(static fn (int $value) => $value * 2);
$schema->sort();
$schema->sort(static fn (int $a, int $b) => $b - $a);

// conversions
$schema->reduce(static fn (int $sum, int $current) => $sum + $current, 0);

backedEnum

use Chubbyphp\Parsing\Parser;

enum BackedSuit: string
{
    case Hearts = 'H';
    case Diamonds = 'D';
    case Clubs = 'C';
    case Spades = 'S';
}

$p = new Parser();

$schema = $p->backedEnum(BackedSuit::class);

$data = $schema->parse('D');

// validations

// transformations

// conversions
$schema->toInt();
$schema->toString();

bool

use Chubbyphp\Parsing\Parser;

$p = new Parser();

$schema = $p->bool();

$data = $schema->parse(true);

// validations

// transformations

// conversions
$schema->toInt();
$schema->toString();

dateTime

use Chubbyphp\Parsing\Parser;

$p = new Parser();

$schema = $p->dateTime();

$data = $schema->parse(new \DateTimeImmutable('2024-01-20T09:15:00+00:00'));

// validations
$schema->from(new \DateTimeImmutable('2024-01-20T09:15:00+00:00'));
$schema->to(new \DateTimeImmutable('2024-01-20T09:15:00+00:00'));

// transformations

// conversions
$schema->toInt();
$schema->toString();

discriminatedUnion

use Chubbyphp\Parsing\Parser;

$p = new Parser();

$schema = $p->discriminatedUnion([
    $p->object(['_type' => $p->literal('email'), 'address' => $p->string()]),
    $p->object(['_type' => $p->literal('phone'), 'number' => $p->string()]),
]);

$data = $schema->parse(['_type' => 'phone', 'number' => '+41790000000']);

float

use Chubbyphp\Parsing\Parser;

$p = new Parser();

$schema = $p->float();

$data = $schema->parse(4.2);

// validations
$schema->gt(5.0);
$schema->gte(5.0);
$schema->lt(5.0);
$schema->lte(5.0);
$schema->positive();
$schema->nonNegative();
$schema->negative();
$schema->nonPositive();

// transformations

// conversions
$schema->toInt();
$schema->toString();

int

use Chubbyphp\Parsing\Parser;

$p = new Parser();

$schema = $p->int();

$data = $schema->parse(1337);

// validations
$schema->gt(5);
$schema->gte(5);
$schema->lt(5);
$schema->lte(5);
$schema->positive();
$schema->nonNegative();
$schema->negative();
$schema->nonPositive();

// transformations

// conversions
$schema->toDateTime();
$schema->toFloat();
$schema->toString();

lazy

use Chubbyphp\Parsing\Parser;

$p = new Parser();

$schema = $p->lazy(static function () use ($p, &$schema) {
    return $p->object([
        'name' => $p->string(),
        'child' => $schema,
    ])->nullable();
});

$data = $schema->parse([
    'name' => 'name1',
    'child' => [
        'name' => 'name2',
        'child' => null
    ],
]);

literal

use Chubbyphp\Parsing\Parser;

$p = new Parser();

$schema = $p->literal('email'); // supports string|float|int|bool

$data = $schema->parse('email');

object

use Chubbyphp\Parsing\Parser;

$p = new Parser();

$schema = $p->object(['name' => $p->string()]);

// stdClass object
$data = $schema->parse(['name' => 'example']);

// SampleClass object
$data = $schema->parse(['name' => 'example'], SampleNamespace\SampleClass::class);

// if the key 'name' does not exist on input, it won't exists on the output
$schema->optional(['name']);

// validations
$schema->strict();
$schema->strict(['_id']); // strip _id if given, but complain about any other additional field

// transformations

// conversions

record

use Chubbyphp\Parsing\Parser;

$p = new Parser();

$schema = $p->record($p->string());

$data = $schema->parse([
    'key1' => 'value1',
    'key2' => 'value2'
]);

respectValidation

composer require respect/validation "^2.3"
use Chubbyphp\Parsing\Parser;
use Respect\Validation\Validator as v;

$p = new Parser();

$schema = $p->respectValidation(v::numericVal()->positive()->between(1, 255));

$data = $schema->parse(5);

string

use Chubbyphp\Parsing\Parser;

$p = new Parser();

$schema = $p->string();

$data = $schema->parse('example');

// validations
$schema->length(5);
$schema->minLength(5);
$schema->maxLength(5);
$schema->includes('amp');
$schema->startsWith('exa');
$schema->endsWith('mpl');
$schema->match('/^[a-z]+$/i');
$schema->email();
$schema->ipV4();
$schema->ipV6();
$schema->url();
$schema->uuidV4();
$schema->uuidV5();

// transformations
$schema->trim();
$schema->trimStart();
$schema->trimEnd();
$schema->toLowerCase();
$schema->toUpperCase();

// conversions
$schema->toDateTime();
$schema->toFloat();
$schema->toInt();

tuple

use Chubbyphp\Parsing\Parser;

$p = new Parser();

$schema = $p->tuple([$p->float(), $p->float()]);

$data = $schema->parse([47.1, 8.2]);

union

use Chubbyphp\Parsing\Parser;

$p = new Parser();

$schema = $p->union([$p->string(), $p->int()]);

$data = $schema->parse('42');

Copyright

2024 Dominik Zogg