169 lines
4.6 KiB
PHP
169 lines
4.6 KiB
PHP
<?php
|
|
|
|
/**
|
|
* League.Csv (https://csv.thephpleague.com)
|
|
*
|
|
* (c) Ignace Nyamagana Butera <nyamsprod@gmail.com>
|
|
*
|
|
* For the full copyright and license information, please view the LICENSE
|
|
* file that was distributed with this source code.
|
|
*/
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace League\Csv\Query\Constraint;
|
|
|
|
use CallbackFilterIterator;
|
|
use Closure;
|
|
use Iterator;
|
|
use League\Csv\MapIterator;
|
|
use League\Csv\Query\Predicate;
|
|
use League\Csv\Query\PredicateCombinator;
|
|
|
|
use function array_reduce;
|
|
|
|
/**
|
|
* @phpstan-import-type Condition from PredicateCombinator
|
|
* @phpstan-import-type ConditionExtended from PredicateCombinator
|
|
*/
|
|
final class Criteria implements PredicateCombinator
|
|
{
|
|
/**
|
|
* @param Condition $predicate
|
|
*/
|
|
private function __construct(private readonly Predicate|Closure $predicate)
|
|
{
|
|
}
|
|
|
|
/**
|
|
* Creates a new instance with predicates join using the logical AND operator.
|
|
*
|
|
* @param ConditionExtended ...$predicates
|
|
*/
|
|
public static function all(Predicate|Closure|callable ...$predicates): self
|
|
{
|
|
return new self(function (mixed $value, int|string $key) use ($predicates): bool {
|
|
foreach ($predicates as $predicate) {
|
|
if (!$predicate($value, $key)) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Creates a new instance with predicates join using the logical NOT operator.
|
|
*
|
|
* @param ConditionExtended ...$predicates
|
|
*/
|
|
public static function none(Predicate|Closure|callable ...$predicates): self
|
|
{
|
|
return new self(function (mixed $value, int|string $key) use ($predicates): bool {
|
|
foreach ($predicates as $predicate) {
|
|
if ($predicate($value, $key)) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Creates a new instance with predicates join using the logical OR operator.
|
|
*
|
|
* @param ConditionExtended ...$predicates
|
|
*/
|
|
public static function any(Predicate|Closure|callable ...$predicates): self
|
|
{
|
|
return new self(function (mixed $value, int|string $key) use ($predicates): bool {
|
|
foreach ($predicates as $predicate) {
|
|
if ($predicate($value, $key)) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Creates a new instance with predicates join using the logical XOR operator.
|
|
*
|
|
* @param ConditionExtended ...$predicates
|
|
*/
|
|
public static function xany(Predicate|Closure|callable ...$predicates): self
|
|
{
|
|
return new self(fn (mixed $value, int|string $key): bool => array_reduce(
|
|
$predicates,
|
|
fn (bool $bool, Predicate|Closure|callable $predicate) => $predicate($value, $key) xor $bool,
|
|
false
|
|
));
|
|
}
|
|
|
|
public function __invoke(mixed $value, int|string $key): bool
|
|
{
|
|
return ($this->predicate)($value, $key);
|
|
}
|
|
|
|
public function filter(iterable $value): Iterator
|
|
{
|
|
return new CallbackFilterIterator(MapIterator::toIterator($value), $this);
|
|
}
|
|
|
|
/**
|
|
* @param ConditionExtended ...$predicates
|
|
*/
|
|
public function and(Predicate|Closure|callable ...$predicates): self
|
|
{
|
|
return self::all($this->predicate, ...$predicates);
|
|
}
|
|
|
|
public function andNot(Predicate|Closure|callable ...$predicates): self
|
|
{
|
|
return self::all($this->predicate, self::none(...$predicates));
|
|
}
|
|
|
|
/**
|
|
* @param ConditionExtended ...$predicates
|
|
*/
|
|
public function not(Predicate|Closure|callable ...$predicates): self
|
|
{
|
|
return self::none($this->predicate, ...$predicates);
|
|
}
|
|
|
|
/**
|
|
* @param ConditionExtended ...$predicates
|
|
*/
|
|
public function or(Predicate|Closure|callable ...$predicates): self
|
|
{
|
|
return self::any($this->predicate, ...$predicates);
|
|
}
|
|
|
|
/**
|
|
* @param ConditionExtended ...$predicates
|
|
*/
|
|
public function orNot(Predicate|Closure|callable ...$predicates): self
|
|
{
|
|
return self::any($this->predicate, self::none(...$predicates));
|
|
}
|
|
|
|
/**
|
|
* @param ConditionExtended ...$predicates
|
|
*/
|
|
public function xor(Predicate|Closure|callable ...$predicates): self
|
|
{
|
|
return self::xany($this->predicate, ...$predicates);
|
|
}
|
|
|
|
/**
|
|
* @param ConditionExtended ...$predicates
|
|
*/
|
|
public function xorNot(Predicate|Closure|callable ...$predicates): self
|
|
{
|
|
return self::xany($this->predicate, self::none(...$predicates));
|
|
}
|
|
}
|