Skip to content

Commit

Permalink
add Is::string()
Browse files Browse the repository at this point in the history
  • Loading branch information
Baptouuuu committed Nov 6, 2023
1 parent 1f0638b commit 5319f72
Show file tree
Hide file tree
Showing 3 changed files with 145 additions and 0 deletions.
45 changes: 45 additions & 0 deletions proofs/is.php
@@ -0,0 +1,45 @@
<?php
declare(strict_types = 1);

use Innmind\Validation\Is;
use Innmind\BlackBox\Set;

return static function() {
yield proof(
'Is::string()',
given(
Set\Strings::any(),
Set\Either::any(
Set\Integers::any(),
Set\Elements::of(
true,
false,
null,
new \stdClass,
),
Set\Sequence::of(Set\Strings::any()),
),
),
static function($assert, $string, $other) {
$assert->true(
Is::string()->asPredicate()($string),
);
$assert->same(
$string,
Is::string()($string)->match(
static fn($value) => $value,
static fn() => null,
),
);
$assert->false(
Is::string()->asPredicate()($other),
);
$assert->null(
Is::string()($other)->match(
static fn($value) => $value,
static fn() => null,
),
);
},
);
};
54 changes: 54 additions & 0 deletions src/Is.php
@@ -0,0 +1,54 @@
<?php
declare(strict_types = 1);

namespace Innmind\Validation;

use Innmind\Immutable\{
Validation,
Predicate as PredicateInterface,
};

/**
* @template-covariant T
* @implements Constraint<mixed, T>
* @psalm-immutable
*/
final class Is implements Constraint
{
/** @var pure-callable(mixed): bool */
private $assert;
/** @var non-empty-string */
private string $type;

/**
* @param pure-callable(mixed): bool $assert
* @param non-empty-string $type
*/
private function __construct(callable $assert, string $type)
{
$this->assert = $assert;
$this->type = $type;
}

public function __invoke(mixed $value): Validation
{
return match (($this->assert)($value)) {
true => Validation::success($value),
false => Validation::fail(Failure::of("Value is not of type {$this->type}")),
};
}

/**
* @return self<string>
*/
public static function string(): self
{
/** @var self<string> */
return new self(\is_string(...), 'string');
}

public function asPredicate(): PredicateInterface
{
return Predicate::of($this);
}
}
46 changes: 46 additions & 0 deletions src/Predicate.php
@@ -0,0 +1,46 @@
<?php
declare(strict_types = 1);

namespace Innmind\Validation;

use Innmind\Immutable\Predicate as PredicateInterface;

/**
* @template T
* @implements PredicateInterface<T>
* @psalm-immutable
*/
final class Predicate implements PredicateInterface
{
/** @var Constraint<mixed, T> */
private Constraint $constraint;

/**
* @param Constraint<mixed, T> $constraint
*/
private function __construct(Constraint $constraint)
{
$this->constraint = $constraint;
}

public function __invoke(mixed $value): bool
{
return ($this->constraint)($value)->match(
static fn() => true,
static fn() => false,
);
}

/**
* @template A
* @psalm-pure
*
* @param Constraint<mixed, A> $constraint
*
* @return self<A>
*/
public static function of(Constraint $constraint): self
{
return new self($constraint);
}
}

0 comments on commit 5319f72

Please sign in to comment.