first commit
This commit is contained in:
171
vendor/ramsey/collection/src/AbstractArray.php
vendored
Normal file
171
vendor/ramsey/collection/src/AbstractArray.php
vendored
Normal file
@ -0,0 +1,171 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the ramsey/collection library
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>
|
||||
* @license http://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ramsey\Collection;
|
||||
|
||||
use ArrayIterator;
|
||||
use Traversable;
|
||||
|
||||
use function count;
|
||||
|
||||
/**
|
||||
* This class provides a basic implementation of `ArrayInterface`, to minimize
|
||||
* the effort required to implement this interface.
|
||||
*
|
||||
* @template T
|
||||
* @implements ArrayInterface<T>
|
||||
*/
|
||||
abstract class AbstractArray implements ArrayInterface
|
||||
{
|
||||
/**
|
||||
* The items of this array.
|
||||
*
|
||||
* @var array<array-key, T>
|
||||
*/
|
||||
protected array $data = [];
|
||||
|
||||
/**
|
||||
* Constructs a new array object.
|
||||
*
|
||||
* @param array<array-key, T> $data The initial items to add to this array.
|
||||
*/
|
||||
public function __construct(array $data = [])
|
||||
{
|
||||
// Invoke offsetSet() for each value added; in this way, sub-classes
|
||||
// may provide additional logic about values added to the array object.
|
||||
foreach ($data as $key => $value) {
|
||||
$this[$key] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an iterator for this array.
|
||||
*
|
||||
* @link http://php.net/manual/en/iteratoraggregate.getiterator.php IteratorAggregate::getIterator()
|
||||
*
|
||||
* @return Traversable<array-key, T>
|
||||
*/
|
||||
public function getIterator(): Traversable
|
||||
{
|
||||
return new ArrayIterator($this->data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns `true` if the given offset exists in this array.
|
||||
*
|
||||
* @link http://php.net/manual/en/arrayaccess.offsetexists.php ArrayAccess::offsetExists()
|
||||
*
|
||||
* @param array-key $offset The offset to check.
|
||||
*/
|
||||
public function offsetExists(mixed $offset): bool
|
||||
{
|
||||
return isset($this->data[$offset]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value at the specified offset.
|
||||
*
|
||||
* @link http://php.net/manual/en/arrayaccess.offsetget.php ArrayAccess::offsetGet()
|
||||
*
|
||||
* @param array-key $offset The offset for which a value should be returned.
|
||||
*
|
||||
* @return T the value stored at the offset, or null if the offset
|
||||
* does not exist.
|
||||
*/
|
||||
public function offsetGet(mixed $offset): mixed
|
||||
{
|
||||
return $this->data[$offset];
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the given value to the given offset in the array.
|
||||
*
|
||||
* @link http://php.net/manual/en/arrayaccess.offsetset.php ArrayAccess::offsetSet()
|
||||
*
|
||||
* @param array-key | null $offset The offset to set. If `null`, the value
|
||||
* may be set at a numerically-indexed offset.
|
||||
* @param T $value The value to set at the given offset.
|
||||
*/
|
||||
public function offsetSet(mixed $offset, mixed $value): void
|
||||
{
|
||||
if ($offset === null) {
|
||||
$this->data[] = $value;
|
||||
} else {
|
||||
$this->data[$offset] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the given offset and its value from the array.
|
||||
*
|
||||
* @link http://php.net/manual/en/arrayaccess.offsetunset.php ArrayAccess::offsetUnset()
|
||||
*
|
||||
* @param array-key $offset The offset to remove from the array.
|
||||
*/
|
||||
public function offsetUnset(mixed $offset): void
|
||||
{
|
||||
unset($this->data[$offset]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns data suitable for PHP serialization.
|
||||
*
|
||||
* @link https://www.php.net/manual/en/language.oop5.magic.php#language.oop5.magic.serialize
|
||||
* @link https://www.php.net/serialize
|
||||
*
|
||||
* @return array<array-key, T>
|
||||
*/
|
||||
public function __serialize(): array
|
||||
{
|
||||
return $this->data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds unserialized data to the object.
|
||||
*
|
||||
* @param array<array-key, T> $data
|
||||
*/
|
||||
public function __unserialize(array $data): void
|
||||
{
|
||||
$this->data = $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of items in this array.
|
||||
*
|
||||
* @link http://php.net/manual/en/countable.count.php Countable::count()
|
||||
*/
|
||||
public function count(): int
|
||||
{
|
||||
return count($this->data);
|
||||
}
|
||||
|
||||
public function clear(): void
|
||||
{
|
||||
$this->data = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function toArray(): array
|
||||
{
|
||||
return $this->data;
|
||||
}
|
||||
|
||||
public function isEmpty(): bool
|
||||
{
|
||||
return $this->data === [];
|
||||
}
|
||||
}
|
393
vendor/ramsey/collection/src/AbstractCollection.php
vendored
Normal file
393
vendor/ramsey/collection/src/AbstractCollection.php
vendored
Normal file
@ -0,0 +1,393 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the ramsey/collection library
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>
|
||||
* @license http://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ramsey\Collection;
|
||||
|
||||
use Closure;
|
||||
use Ramsey\Collection\Exception\CollectionMismatchException;
|
||||
use Ramsey\Collection\Exception\InvalidArgumentException;
|
||||
use Ramsey\Collection\Exception\InvalidPropertyOrMethod;
|
||||
use Ramsey\Collection\Exception\NoSuchElementException;
|
||||
use Ramsey\Collection\Exception\UnsupportedOperationException;
|
||||
use Ramsey\Collection\Tool\TypeTrait;
|
||||
use Ramsey\Collection\Tool\ValueExtractorTrait;
|
||||
use Ramsey\Collection\Tool\ValueToStringTrait;
|
||||
|
||||
use function array_filter;
|
||||
use function array_key_first;
|
||||
use function array_key_last;
|
||||
use function array_map;
|
||||
use function array_merge;
|
||||
use function array_reduce;
|
||||
use function array_search;
|
||||
use function array_udiff;
|
||||
use function array_uintersect;
|
||||
use function in_array;
|
||||
use function is_int;
|
||||
use function is_object;
|
||||
use function spl_object_id;
|
||||
use function sprintf;
|
||||
use function usort;
|
||||
|
||||
/**
|
||||
* This class provides a basic implementation of `CollectionInterface`, to
|
||||
* minimize the effort required to implement this interface
|
||||
*
|
||||
* @template T
|
||||
* @extends AbstractArray<T>
|
||||
* @implements CollectionInterface<T>
|
||||
*/
|
||||
abstract class AbstractCollection extends AbstractArray implements CollectionInterface
|
||||
{
|
||||
use TypeTrait;
|
||||
use ValueToStringTrait;
|
||||
use ValueExtractorTrait;
|
||||
|
||||
/**
|
||||
* @throws InvalidArgumentException if $element is of the wrong type.
|
||||
*/
|
||||
public function add(mixed $element): bool
|
||||
{
|
||||
$this[] = $element;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function contains(mixed $element, bool $strict = true): bool
|
||||
{
|
||||
return in_array($element, $this->data, $strict);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws InvalidArgumentException if $element is of the wrong type.
|
||||
*/
|
||||
public function offsetSet(mixed $offset, mixed $value): void
|
||||
{
|
||||
if ($this->checkType($this->getType(), $value) === false) {
|
||||
throw new InvalidArgumentException(
|
||||
'Value must be of type ' . $this->getType() . '; value is '
|
||||
. $this->toolValueToString($value),
|
||||
);
|
||||
}
|
||||
|
||||
if ($offset === null) {
|
||||
$this->data[] = $value;
|
||||
} else {
|
||||
$this->data[$offset] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
public function remove(mixed $element): bool
|
||||
{
|
||||
if (($position = array_search($element, $this->data, true)) !== false) {
|
||||
unset($this[$position]);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws InvalidPropertyOrMethod if the $propertyOrMethod does not exist
|
||||
* on the elements in this collection.
|
||||
* @throws UnsupportedOperationException if unable to call column() on this
|
||||
* collection.
|
||||
*
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function column(string $propertyOrMethod): array
|
||||
{
|
||||
$temp = [];
|
||||
|
||||
foreach ($this->data as $item) {
|
||||
/** @psalm-suppress MixedAssignment */
|
||||
$temp[] = $this->extractValue($item, $propertyOrMethod);
|
||||
}
|
||||
|
||||
return $temp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return T
|
||||
*
|
||||
* @throws NoSuchElementException if this collection is empty.
|
||||
*/
|
||||
public function first(): mixed
|
||||
{
|
||||
$firstIndex = array_key_first($this->data);
|
||||
|
||||
if ($firstIndex === null) {
|
||||
throw new NoSuchElementException('Can\'t determine first item. Collection is empty');
|
||||
}
|
||||
|
||||
return $this->data[$firstIndex];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return T
|
||||
*
|
||||
* @throws NoSuchElementException if this collection is empty.
|
||||
*/
|
||||
public function last(): mixed
|
||||
{
|
||||
$lastIndex = array_key_last($this->data);
|
||||
|
||||
if ($lastIndex === null) {
|
||||
throw new NoSuchElementException('Can\'t determine last item. Collection is empty');
|
||||
}
|
||||
|
||||
return $this->data[$lastIndex];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return CollectionInterface<T>
|
||||
*
|
||||
* @throws InvalidPropertyOrMethod if the $propertyOrMethod does not exist
|
||||
* on the elements in this collection.
|
||||
* @throws UnsupportedOperationException if unable to call sort() on this
|
||||
* collection.
|
||||
*/
|
||||
public function sort(?string $propertyOrMethod = null, Sort $order = Sort::Ascending): CollectionInterface
|
||||
{
|
||||
$collection = clone $this;
|
||||
|
||||
usort(
|
||||
$collection->data,
|
||||
/**
|
||||
* @param T $a
|
||||
* @param T $b
|
||||
*/
|
||||
function (mixed $a, mixed $b) use ($propertyOrMethod, $order): int {
|
||||
/** @var mixed $aValue */
|
||||
$aValue = $this->extractValue($a, $propertyOrMethod);
|
||||
|
||||
/** @var mixed $bValue */
|
||||
$bValue = $this->extractValue($b, $propertyOrMethod);
|
||||
|
||||
return ($aValue <=> $bValue) * ($order === Sort::Descending ? -1 : 1);
|
||||
},
|
||||
);
|
||||
|
||||
return $collection;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param callable(T): bool $callback A callable to use for filtering elements.
|
||||
*
|
||||
* @return CollectionInterface<T>
|
||||
*/
|
||||
public function filter(callable $callback): CollectionInterface
|
||||
{
|
||||
$collection = clone $this;
|
||||
$collection->data = array_merge([], array_filter($collection->data, $callback));
|
||||
|
||||
return $collection;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return CollectionInterface<T>
|
||||
*
|
||||
* @throws InvalidPropertyOrMethod if the $propertyOrMethod does not exist
|
||||
* on the elements in this collection.
|
||||
* @throws UnsupportedOperationException if unable to call where() on this
|
||||
* collection.
|
||||
*/
|
||||
public function where(?string $propertyOrMethod, mixed $value): CollectionInterface
|
||||
{
|
||||
return $this->filter(
|
||||
/**
|
||||
* @param T $item
|
||||
*/
|
||||
function (mixed $item) use ($propertyOrMethod, $value): bool {
|
||||
/** @var mixed $accessorValue */
|
||||
$accessorValue = $this->extractValue($item, $propertyOrMethod);
|
||||
|
||||
return $accessorValue === $value;
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param callable(T): TCallbackReturn $callback A callable to apply to each
|
||||
* item of the collection.
|
||||
*
|
||||
* @return CollectionInterface<TCallbackReturn>
|
||||
*
|
||||
* @template TCallbackReturn
|
||||
*/
|
||||
public function map(callable $callback): CollectionInterface
|
||||
{
|
||||
/** @var Collection<TCallbackReturn> */
|
||||
return new Collection('mixed', array_map($callback, $this->data));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param callable(TCarry, T): TCarry $callback A callable to apply to each
|
||||
* item of the collection to reduce it to a single value.
|
||||
* @param TCarry $initial This is the initial value provided to the callback.
|
||||
*
|
||||
* @return TCarry
|
||||
*
|
||||
* @template TCarry
|
||||
*/
|
||||
public function reduce(callable $callback, mixed $initial): mixed
|
||||
{
|
||||
/** @var TCarry */
|
||||
return array_reduce($this->data, $callback, $initial);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param CollectionInterface<T> $other The collection to check for divergent
|
||||
* items.
|
||||
*
|
||||
* @return CollectionInterface<T>
|
||||
*
|
||||
* @throws CollectionMismatchException if the compared collections are of
|
||||
* differing types.
|
||||
*/
|
||||
public function diff(CollectionInterface $other): CollectionInterface
|
||||
{
|
||||
$this->compareCollectionTypes($other);
|
||||
|
||||
$diffAtoB = array_udiff($this->data, $other->toArray(), $this->getComparator());
|
||||
$diffBtoA = array_udiff($other->toArray(), $this->data, $this->getComparator());
|
||||
|
||||
/** @var array<array-key, T> $diff */
|
||||
$diff = array_merge($diffAtoB, $diffBtoA);
|
||||
|
||||
$collection = clone $this;
|
||||
$collection->data = $diff;
|
||||
|
||||
return $collection;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param CollectionInterface<T> $other The collection to check for
|
||||
* intersecting items.
|
||||
*
|
||||
* @return CollectionInterface<T>
|
||||
*
|
||||
* @throws CollectionMismatchException if the compared collections are of
|
||||
* differing types.
|
||||
*/
|
||||
public function intersect(CollectionInterface $other): CollectionInterface
|
||||
{
|
||||
$this->compareCollectionTypes($other);
|
||||
|
||||
/** @var array<array-key, T> $intersect */
|
||||
$intersect = array_uintersect($this->data, $other->toArray(), $this->getComparator());
|
||||
|
||||
$collection = clone $this;
|
||||
$collection->data = $intersect;
|
||||
|
||||
return $collection;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param CollectionInterface<T> ...$collections The collections to merge.
|
||||
*
|
||||
* @return CollectionInterface<T>
|
||||
*
|
||||
* @throws CollectionMismatchException if unable to merge any of the given
|
||||
* collections or items within the given collections due to type
|
||||
* mismatch errors.
|
||||
*/
|
||||
public function merge(CollectionInterface ...$collections): CollectionInterface
|
||||
{
|
||||
$mergedCollection = clone $this;
|
||||
|
||||
foreach ($collections as $index => $collection) {
|
||||
if (!$collection instanceof static) {
|
||||
throw new CollectionMismatchException(
|
||||
sprintf('Collection with index %d must be of type %s', $index, static::class),
|
||||
);
|
||||
}
|
||||
|
||||
// When using generics (Collection.php, Set.php, etc),
|
||||
// we also need to make sure that the internal types match each other
|
||||
if ($this->getUniformType($collection) !== $this->getUniformType($this)) {
|
||||
throw new CollectionMismatchException(
|
||||
sprintf(
|
||||
'Collection items in collection with index %d must be of type %s',
|
||||
$index,
|
||||
$this->getType(),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
foreach ($collection as $key => $value) {
|
||||
if (is_int($key)) {
|
||||
$mergedCollection[] = $value;
|
||||
} else {
|
||||
$mergedCollection[$key] = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $mergedCollection;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param CollectionInterface<T> $other
|
||||
*
|
||||
* @throws CollectionMismatchException
|
||||
*/
|
||||
private function compareCollectionTypes(CollectionInterface $other): void
|
||||
{
|
||||
if (!$other instanceof static) {
|
||||
throw new CollectionMismatchException('Collection must be of type ' . static::class);
|
||||
}
|
||||
|
||||
// When using generics (Collection.php, Set.php, etc),
|
||||
// we also need to make sure that the internal types match each other
|
||||
if ($this->getUniformType($other) !== $this->getUniformType($this)) {
|
||||
throw new CollectionMismatchException('Collection items must be of type ' . $this->getType());
|
||||
}
|
||||
}
|
||||
|
||||
private function getComparator(): Closure
|
||||
{
|
||||
return /**
|
||||
* @param T $a
|
||||
* @param T $b
|
||||
*/
|
||||
function (mixed $a, mixed $b): int {
|
||||
// If the two values are object, we convert them to unique scalars.
|
||||
// If the collection contains mixed values (unlikely) where some are objects
|
||||
// and some are not, we leave them as they are.
|
||||
// The comparator should still work and the result of $a < $b should
|
||||
// be consistent but unpredictable since not documented.
|
||||
if (is_object($a) && is_object($b)) {
|
||||
$a = spl_object_id($a);
|
||||
$b = spl_object_id($b);
|
||||
}
|
||||
|
||||
return $a === $b ? 0 : ($a < $b ? 1 : -1);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @param CollectionInterface<mixed> $collection
|
||||
*/
|
||||
private function getUniformType(CollectionInterface $collection): string
|
||||
{
|
||||
return match ($collection->getType()) {
|
||||
'integer' => 'int',
|
||||
'boolean' => 'bool',
|
||||
'double' => 'float',
|
||||
default => $collection->getType(),
|
||||
};
|
||||
}
|
||||
}
|
44
vendor/ramsey/collection/src/AbstractSet.php
vendored
Normal file
44
vendor/ramsey/collection/src/AbstractSet.php
vendored
Normal file
@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the ramsey/collection library
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>
|
||||
* @license http://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ramsey\Collection;
|
||||
|
||||
/**
|
||||
* This class contains the basic implementation of a collection that does not
|
||||
* allow duplicated values (a set), to minimize the effort required to implement
|
||||
* this specific type of collection.
|
||||
*
|
||||
* @template T
|
||||
* @extends AbstractCollection<T>
|
||||
*/
|
||||
abstract class AbstractSet extends AbstractCollection
|
||||
{
|
||||
public function add(mixed $element): bool
|
||||
{
|
||||
if ($this->contains($element)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return parent::add($element);
|
||||
}
|
||||
|
||||
public function offsetSet(mixed $offset, mixed $value): void
|
||||
{
|
||||
if ($this->contains($value)) {
|
||||
return;
|
||||
}
|
||||
|
||||
parent::offsetSet($offset, $value);
|
||||
}
|
||||
}
|
49
vendor/ramsey/collection/src/ArrayInterface.php
vendored
Normal file
49
vendor/ramsey/collection/src/ArrayInterface.php
vendored
Normal file
@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the ramsey/collection library
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>
|
||||
* @license http://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ramsey\Collection;
|
||||
|
||||
use ArrayAccess;
|
||||
use Countable;
|
||||
use IteratorAggregate;
|
||||
|
||||
/**
|
||||
* `ArrayInterface` provides traversable array functionality to data types.
|
||||
*
|
||||
* @template T
|
||||
* @extends ArrayAccess<array-key, T>
|
||||
* @extends IteratorAggregate<array-key, T>
|
||||
*/
|
||||
interface ArrayInterface extends
|
||||
ArrayAccess,
|
||||
Countable,
|
||||
IteratorAggregate
|
||||
{
|
||||
/**
|
||||
* Removes all items from this array.
|
||||
*/
|
||||
public function clear(): void;
|
||||
|
||||
/**
|
||||
* Returns a native PHP array representation of this array object.
|
||||
*
|
||||
* @return array<array-key, T>
|
||||
*/
|
||||
public function toArray(): array;
|
||||
|
||||
/**
|
||||
* Returns `true` if this array is empty.
|
||||
*/
|
||||
public function isEmpty(): bool;
|
||||
}
|
95
vendor/ramsey/collection/src/Collection.php
vendored
Normal file
95
vendor/ramsey/collection/src/Collection.php
vendored
Normal file
@ -0,0 +1,95 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the ramsey/collection library
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>
|
||||
* @license http://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ramsey\Collection;
|
||||
|
||||
/**
|
||||
* A collection represents a group of objects.
|
||||
*
|
||||
* Each object in the collection is of a specific, defined type.
|
||||
*
|
||||
* This is a direct implementation of `CollectionInterface`, provided for
|
||||
* the sake of convenience.
|
||||
*
|
||||
* Example usage:
|
||||
*
|
||||
* ``` php
|
||||
* $collection = new \Ramsey\Collection\Collection('My\\Foo');
|
||||
* $collection->add(new \My\Foo());
|
||||
* $collection->add(new \My\Foo());
|
||||
*
|
||||
* foreach ($collection as $foo) {
|
||||
* // Do something with $foo
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* It is preferable to subclass `AbstractCollection` to create your own typed
|
||||
* collections. For example:
|
||||
*
|
||||
* ``` php
|
||||
* namespace My\Foo;
|
||||
*
|
||||
* class FooCollection extends \Ramsey\Collection\AbstractCollection
|
||||
* {
|
||||
* public function getType()
|
||||
* {
|
||||
* return 'My\\Foo';
|
||||
* }
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* And then use it similarly to the earlier example:
|
||||
*
|
||||
* ``` php
|
||||
* $fooCollection = new \My\Foo\FooCollection();
|
||||
* $fooCollection->add(new \My\Foo());
|
||||
* $fooCollection->add(new \My\Foo());
|
||||
*
|
||||
* foreach ($fooCollection as $foo) {
|
||||
* // Do something with $foo
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* The benefit with this approach is that you may do type-checking on the
|
||||
* collection object:
|
||||
*
|
||||
* ``` php
|
||||
* if ($collection instanceof \My\Foo\FooCollection) {
|
||||
* // the collection is a collection of My\Foo objects
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* @template T
|
||||
* @extends AbstractCollection<T>
|
||||
*/
|
||||
class Collection extends AbstractCollection
|
||||
{
|
||||
/**
|
||||
* Constructs a collection object of the specified type, optionally with the
|
||||
* specified data.
|
||||
*
|
||||
* @param string $collectionType The type or class name associated with this
|
||||
* collection.
|
||||
* @param array<array-key, T> $data The initial items to store in the collection.
|
||||
*/
|
||||
public function __construct(private readonly string $collectionType, array $data = [])
|
||||
{
|
||||
parent::__construct($data);
|
||||
}
|
||||
|
||||
public function getType(): string
|
||||
{
|
||||
return $this->collectionType;
|
||||
}
|
||||
}
|
253
vendor/ramsey/collection/src/CollectionInterface.php
vendored
Normal file
253
vendor/ramsey/collection/src/CollectionInterface.php
vendored
Normal file
@ -0,0 +1,253 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the ramsey/collection library
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>
|
||||
* @license http://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ramsey\Collection;
|
||||
|
||||
use Ramsey\Collection\Exception\CollectionMismatchException;
|
||||
use Ramsey\Collection\Exception\InvalidArgumentException;
|
||||
use Ramsey\Collection\Exception\InvalidPropertyOrMethod;
|
||||
use Ramsey\Collection\Exception\NoSuchElementException;
|
||||
use Ramsey\Collection\Exception\UnsupportedOperationException;
|
||||
|
||||
/**
|
||||
* A collection represents a group of values, known as its elements.
|
||||
*
|
||||
* Some collections allow duplicate elements and others do not. Some are ordered
|
||||
* and others unordered.
|
||||
*
|
||||
* @template T
|
||||
* @extends ArrayInterface<T>
|
||||
*/
|
||||
interface CollectionInterface extends ArrayInterface
|
||||
{
|
||||
/**
|
||||
* Ensures that this collection contains the specified element (optional
|
||||
* operation).
|
||||
*
|
||||
* Returns `true` if this collection changed as a result of the call.
|
||||
* (Returns `false` if this collection does not permit duplicates and
|
||||
* already contains the specified element.)
|
||||
*
|
||||
* Collections that support this operation may place limitations on what
|
||||
* elements may be added to this collection. In particular, some
|
||||
* collections will refuse to add `null` elements, and others will impose
|
||||
* restrictions on the type of elements that may be added. Collection
|
||||
* classes should clearly specify in their documentation any restrictions
|
||||
* on what elements may be added.
|
||||
*
|
||||
* If a collection refuses to add a particular element for any reason other
|
||||
* than that it already contains the element, it must throw an exception
|
||||
* (rather than returning `false`). This preserves the invariant that a
|
||||
* collection always contains the specified element after this call returns.
|
||||
*
|
||||
* @param T $element The element to add to the collection.
|
||||
*
|
||||
* @return bool `true` if this collection changed as a result of the call.
|
||||
*
|
||||
* @throws InvalidArgumentException if the collection refuses to add the
|
||||
* $element for any reason other than that it already contains the element.
|
||||
*/
|
||||
public function add(mixed $element): bool;
|
||||
|
||||
/**
|
||||
* Returns `true` if this collection contains the specified element.
|
||||
*
|
||||
* @param T $element The element to check whether the collection contains.
|
||||
* @param bool $strict Whether to perform a strict type check on the value.
|
||||
*/
|
||||
public function contains(mixed $element, bool $strict = true): bool;
|
||||
|
||||
/**
|
||||
* Returns the type associated with this collection.
|
||||
*/
|
||||
public function getType(): string;
|
||||
|
||||
/**
|
||||
* Removes a single instance of the specified element from this collection,
|
||||
* if it is present.
|
||||
*
|
||||
* @param T $element The element to remove from the collection.
|
||||
*
|
||||
* @return bool `true` if an element was removed as a result of this call.
|
||||
*/
|
||||
public function remove(mixed $element): bool;
|
||||
|
||||
/**
|
||||
* Returns the values from the given property, method, or array key.
|
||||
*
|
||||
* @param string $propertyOrMethod The name of the property, method, or
|
||||
* array key to evaluate and return.
|
||||
*
|
||||
* @return array<int, mixed>
|
||||
*
|
||||
* @throws InvalidPropertyOrMethod if the $propertyOrMethod does not exist
|
||||
* on the elements in this collection.
|
||||
* @throws UnsupportedOperationException if unable to call column() on this
|
||||
* collection.
|
||||
*/
|
||||
public function column(string $propertyOrMethod): array;
|
||||
|
||||
/**
|
||||
* Returns the first item of the collection.
|
||||
*
|
||||
* @return T
|
||||
*
|
||||
* @throws NoSuchElementException if this collection is empty.
|
||||
*/
|
||||
public function first(): mixed;
|
||||
|
||||
/**
|
||||
* Returns the last item of the collection.
|
||||
*
|
||||
* @return T
|
||||
*
|
||||
* @throws NoSuchElementException if this collection is empty.
|
||||
*/
|
||||
public function last(): mixed;
|
||||
|
||||
/**
|
||||
* Sort the collection by a property, method, or array key with the given
|
||||
* sort order.
|
||||
*
|
||||
* If $propertyOrMethod is `null`, this will sort by comparing each element.
|
||||
*
|
||||
* This will always leave the original collection untouched and will return
|
||||
* a new one.
|
||||
*
|
||||
* @param string | null $propertyOrMethod The property, method, or array key
|
||||
* to sort by.
|
||||
* @param Sort $order The sort order for the resulting collection.
|
||||
*
|
||||
* @return CollectionInterface<T>
|
||||
*
|
||||
* @throws InvalidPropertyOrMethod if the $propertyOrMethod does not exist
|
||||
* on the elements in this collection.
|
||||
* @throws UnsupportedOperationException if unable to call sort() on this
|
||||
* collection.
|
||||
*/
|
||||
public function sort(?string $propertyOrMethod = null, Sort $order = Sort::Ascending): self;
|
||||
|
||||
/**
|
||||
* Filter out items of the collection which don't match the criteria of
|
||||
* given callback.
|
||||
*
|
||||
* This will always leave the original collection untouched and will return
|
||||
* a new one.
|
||||
*
|
||||
* See the {@link http://php.net/manual/en/function.array-filter.php PHP array_filter() documentation}
|
||||
* for examples of how the `$callback` parameter works.
|
||||
*
|
||||
* @param callable(T): bool $callback A callable to use for filtering elements.
|
||||
*
|
||||
* @return CollectionInterface<T>
|
||||
*/
|
||||
public function filter(callable $callback): self;
|
||||
|
||||
/**
|
||||
* Create a new collection where the result of the given property, method,
|
||||
* or array key of each item in the collection equals the given value.
|
||||
*
|
||||
* This will always leave the original collection untouched and will return
|
||||
* a new one.
|
||||
*
|
||||
* @param string | null $propertyOrMethod The property, method, or array key
|
||||
* to evaluate. If `null`, the element itself is compared to $value.
|
||||
* @param mixed $value The value to match.
|
||||
*
|
||||
* @return CollectionInterface<T>
|
||||
*
|
||||
* @throws InvalidPropertyOrMethod if the $propertyOrMethod does not exist
|
||||
* on the elements in this collection.
|
||||
* @throws UnsupportedOperationException if unable to call where() on this
|
||||
* collection.
|
||||
*/
|
||||
public function where(?string $propertyOrMethod, mixed $value): self;
|
||||
|
||||
/**
|
||||
* Apply a given callback method on each item of the collection.
|
||||
*
|
||||
* This will always leave the original collection untouched. The new
|
||||
* collection is created by mapping the callback to each item of the
|
||||
* original collection.
|
||||
*
|
||||
* See the {@link http://php.net/manual/en/function.array-map.php PHP array_map() documentation}
|
||||
* for examples of how the `$callback` parameter works.
|
||||
*
|
||||
* @param callable(T): TCallbackReturn $callback A callable to apply to each
|
||||
* item of the collection.
|
||||
*
|
||||
* @return CollectionInterface<TCallbackReturn>
|
||||
*
|
||||
* @template TCallbackReturn
|
||||
*/
|
||||
public function map(callable $callback): self;
|
||||
|
||||
/**
|
||||
* Apply a given callback method on each item of the collection
|
||||
* to reduce it to a single value.
|
||||
*
|
||||
* See the {@link http://php.net/manual/en/function.array-reduce.php PHP array_reduce() documentation}
|
||||
* for examples of how the `$callback` and `$initial` parameters work.
|
||||
*
|
||||
* @param callable(TCarry, T): TCarry $callback A callable to apply to each
|
||||
* item of the collection to reduce it to a single value.
|
||||
* @param TCarry $initial This is the initial value provided to the callback.
|
||||
*
|
||||
* @return TCarry
|
||||
*
|
||||
* @template TCarry
|
||||
*/
|
||||
public function reduce(callable $callback, mixed $initial): mixed;
|
||||
|
||||
/**
|
||||
* Create a new collection with divergent items between current and given
|
||||
* collection.
|
||||
*
|
||||
* @param CollectionInterface<T> $other The collection to check for divergent
|
||||
* items.
|
||||
*
|
||||
* @return CollectionInterface<T>
|
||||
*
|
||||
* @throws CollectionMismatchException if the compared collections are of
|
||||
* differing types.
|
||||
*/
|
||||
public function diff(CollectionInterface $other): self;
|
||||
|
||||
/**
|
||||
* Create a new collection with intersecting item between current and given
|
||||
* collection.
|
||||
*
|
||||
* @param CollectionInterface<T> $other The collection to check for
|
||||
* intersecting items.
|
||||
*
|
||||
* @return CollectionInterface<T>
|
||||
*
|
||||
* @throws CollectionMismatchException if the compared collections are of
|
||||
* differing types.
|
||||
*/
|
||||
public function intersect(CollectionInterface $other): self;
|
||||
|
||||
/**
|
||||
* Merge current items and items of given collections into a new one.
|
||||
*
|
||||
* @param CollectionInterface<T> ...$collections The collections to merge.
|
||||
*
|
||||
* @return CollectionInterface<T>
|
||||
*
|
||||
* @throws CollectionMismatchException if unable to merge any of the given
|
||||
* collections or items within the given collections due to type
|
||||
* mismatch errors.
|
||||
*/
|
||||
public function merge(CollectionInterface ...$collections): self;
|
||||
}
|
166
vendor/ramsey/collection/src/DoubleEndedQueue.php
vendored
Normal file
166
vendor/ramsey/collection/src/DoubleEndedQueue.php
vendored
Normal file
@ -0,0 +1,166 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the ramsey/collection library
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>
|
||||
* @license http://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ramsey\Collection;
|
||||
|
||||
use Ramsey\Collection\Exception\InvalidArgumentException;
|
||||
use Ramsey\Collection\Exception\NoSuchElementException;
|
||||
|
||||
use function array_key_last;
|
||||
use function array_pop;
|
||||
use function array_unshift;
|
||||
|
||||
/**
|
||||
* This class provides a basic implementation of `DoubleEndedQueueInterface`, to
|
||||
* minimize the effort required to implement this interface.
|
||||
*
|
||||
* @template T
|
||||
* @extends Queue<T>
|
||||
* @implements DoubleEndedQueueInterface<T>
|
||||
*/
|
||||
class DoubleEndedQueue extends Queue implements DoubleEndedQueueInterface
|
||||
{
|
||||
/**
|
||||
* Constructs a double-ended queue (dequeue) object of the specified type,
|
||||
* optionally with the specified data.
|
||||
*
|
||||
* @param string $queueType The type or class name associated with this dequeue.
|
||||
* @param array<array-key, T> $data The initial items to store in the dequeue.
|
||||
*/
|
||||
public function __construct(private readonly string $queueType, array $data = [])
|
||||
{
|
||||
parent::__construct($this->queueType, $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws InvalidArgumentException if $element is of the wrong type
|
||||
*/
|
||||
public function addFirst(mixed $element): bool
|
||||
{
|
||||
if ($this->checkType($this->getType(), $element) === false) {
|
||||
throw new InvalidArgumentException(
|
||||
'Value must be of type ' . $this->getType() . '; value is '
|
||||
. $this->toolValueToString($element),
|
||||
);
|
||||
}
|
||||
|
||||
array_unshift($this->data, $element);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws InvalidArgumentException if $element is of the wrong type
|
||||
*/
|
||||
public function addLast(mixed $element): bool
|
||||
{
|
||||
return $this->add($element);
|
||||
}
|
||||
|
||||
public function offerFirst(mixed $element): bool
|
||||
{
|
||||
try {
|
||||
return $this->addFirst($element);
|
||||
} catch (InvalidArgumentException) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public function offerLast(mixed $element): bool
|
||||
{
|
||||
return $this->offer($element);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return T the first element in this queue.
|
||||
*
|
||||
* @throws NoSuchElementException if the queue is empty
|
||||
*/
|
||||
public function removeFirst(): mixed
|
||||
{
|
||||
return $this->remove();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return T the last element in this queue.
|
||||
*
|
||||
* @throws NoSuchElementException if this queue is empty.
|
||||
*/
|
||||
public function removeLast(): mixed
|
||||
{
|
||||
return $this->pollLast() ?? throw new NoSuchElementException(
|
||||
'Can\'t return element from Queue. Queue is empty.',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return T | null the head of this queue, or `null` if this queue is empty.
|
||||
*/
|
||||
public function pollFirst(): mixed
|
||||
{
|
||||
return $this->poll();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return T | null the tail of this queue, or `null` if this queue is empty.
|
||||
*/
|
||||
public function pollLast(): mixed
|
||||
{
|
||||
return array_pop($this->data);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return T the head of this queue.
|
||||
*
|
||||
* @throws NoSuchElementException if this queue is empty.
|
||||
*/
|
||||
public function firstElement(): mixed
|
||||
{
|
||||
return $this->element();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return T the tail of this queue.
|
||||
*
|
||||
* @throws NoSuchElementException if this queue is empty.
|
||||
*/
|
||||
public function lastElement(): mixed
|
||||
{
|
||||
return $this->peekLast() ?? throw new NoSuchElementException(
|
||||
'Can\'t return element from Queue. Queue is empty.',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return T | null the head of this queue, or `null` if this queue is empty.
|
||||
*/
|
||||
public function peekFirst(): mixed
|
||||
{
|
||||
return $this->peek();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return T | null the tail of this queue, or `null` if this queue is empty.
|
||||
*/
|
||||
public function peekLast(): mixed
|
||||
{
|
||||
$lastIndex = array_key_last($this->data);
|
||||
|
||||
if ($lastIndex === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $this->data[$lastIndex];
|
||||
}
|
||||
}
|
313
vendor/ramsey/collection/src/DoubleEndedQueueInterface.php
vendored
Normal file
313
vendor/ramsey/collection/src/DoubleEndedQueueInterface.php
vendored
Normal file
@ -0,0 +1,313 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the ramsey/collection library
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>
|
||||
* @license http://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ramsey\Collection;
|
||||
|
||||
use Ramsey\Collection\Exception\NoSuchElementException;
|
||||
use RuntimeException;
|
||||
|
||||
/**
|
||||
* A linear collection that supports element insertion and removal at both ends.
|
||||
*
|
||||
* Most `DoubleEndedQueueInterface` implementations place no fixed limits on the
|
||||
* number of elements they may contain, but this interface supports
|
||||
* capacity-restricted double-ended queues as well as those with no fixed size
|
||||
* limit.
|
||||
*
|
||||
* This interface defines methods to access the elements at both ends of the
|
||||
* double-ended queue. Methods are provided to insert, remove, and examine the
|
||||
* element. Each of these methods exists in two forms: one throws an exception
|
||||
* if the operation fails, the other returns a special value (either `null` or
|
||||
* `false`, depending on the operation). The latter form of the insert operation
|
||||
* is designed specifically for use with capacity-restricted implementations; in
|
||||
* most implementations, insert operations cannot fail.
|
||||
*
|
||||
* The twelve methods described above are summarized in the following table:
|
||||
*
|
||||
* <table>
|
||||
* <caption>Summary of DoubleEndedQueueInterface methods</caption>
|
||||
* <thead>
|
||||
* <tr>
|
||||
* <th></th>
|
||||
* <th colspan=2>First Element (Head)</th>
|
||||
* <th colspan=2>Last Element (Tail)</th>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td></td>
|
||||
* <td><em>Throws exception</em></td>
|
||||
* <td><em>Special value</em></td>
|
||||
* <td><em>Throws exception</em></td>
|
||||
* <td><em>Special value</em></td>
|
||||
* </tr>
|
||||
* </thead>
|
||||
* <tbody>
|
||||
* <tr>
|
||||
* <th>Insert</th>
|
||||
* <td><code>addFirst()</code></td>
|
||||
* <td><code>offerFirst()</code></td>
|
||||
* <td><code>addLast()</code></td>
|
||||
* <td><code>offerLast()</code></td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <th>Remove</th>
|
||||
* <td><code>removeFirst()</code></td>
|
||||
* <td><code>pollFirst()</code></td>
|
||||
* <td><code>removeLast()</code></td>
|
||||
* <td><code>pollLast()</code></td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <th>Examine</th>
|
||||
* <td><code>firstElement()</code></td>
|
||||
* <td><code>peekFirst()</code></td>
|
||||
* <td><code>lastElement()</code></td>
|
||||
* <td><code>peekLast()</code></td>
|
||||
* </tr>
|
||||
* </tbody>
|
||||
* </table>
|
||||
*
|
||||
* This interface extends the `QueueInterface`. When a double-ended queue is
|
||||
* used as a queue, FIFO (first-in-first-out) behavior results. Elements are
|
||||
* added at the end of the double-ended queue and removed from the beginning.
|
||||
* The methods inherited from the `QueueInterface` are precisely equivalent to
|
||||
* `DoubleEndedQueueInterface` methods as indicated in the following table:
|
||||
*
|
||||
* <table>
|
||||
* <caption>Comparison of QueueInterface and DoubleEndedQueueInterface methods</caption>
|
||||
* <thead>
|
||||
* <tr>
|
||||
* <th>QueueInterface Method</th>
|
||||
* <th>DoubleEndedQueueInterface Method</th>
|
||||
* </tr>
|
||||
* </thead>
|
||||
* <tbody>
|
||||
* <tr>
|
||||
* <td><code>add()</code></td>
|
||||
* <td><code>addLast()</code></td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><code>offer()</code></td>
|
||||
* <td><code>offerLast()</code></td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><code>remove()</code></td>
|
||||
* <td><code>removeFirst()</code></td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><code>poll()</code></td>
|
||||
* <td><code>pollFirst()</code></td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><code>element()</code></td>
|
||||
* <td><code>firstElement()</code></td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><code>peek()</code></td>
|
||||
* <td><code>peekFirst()</code></td>
|
||||
* </tr>
|
||||
* </tbody>
|
||||
* </table>
|
||||
*
|
||||
* Double-ended queues can also be used as LIFO (last-in-first-out) stacks. When
|
||||
* a double-ended queue is used as a stack, elements are pushed and popped from
|
||||
* the beginning of the double-ended queue. Stack concepts are precisely
|
||||
* equivalent to `DoubleEndedQueueInterface` methods as indicated in the table
|
||||
* below:
|
||||
*
|
||||
* <table>
|
||||
* <caption>Comparison of stack concepts and DoubleEndedQueueInterface methods</caption>
|
||||
* <thead>
|
||||
* <tr>
|
||||
* <th>Stack concept</th>
|
||||
* <th>DoubleEndedQueueInterface Method</th>
|
||||
* </tr>
|
||||
* </thead>
|
||||
* <tbody>
|
||||
* <tr>
|
||||
* <td><em>push</em></td>
|
||||
* <td><code>addFirst()</code></td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><em>pop</em></td>
|
||||
* <td><code>removeFirst()</code></td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><em>peek</em></td>
|
||||
* <td><code>peekFirst()</code></td>
|
||||
* </tr>
|
||||
* </tbody>
|
||||
* </table>
|
||||
*
|
||||
* Note that the `peek()` method works equally well when a double-ended queue is
|
||||
* used as a queue or a stack; in either case, elements are drawn from the
|
||||
* beginning of the double-ended queue.
|
||||
*
|
||||
* While `DoubleEndedQueueInterface` implementations are not strictly required
|
||||
* to prohibit the insertion of `null` elements, they are strongly encouraged to
|
||||
* do so. Users of any `DoubleEndedQueueInterface` implementations that do allow
|
||||
* `null` elements are strongly encouraged *not* to take advantage of the
|
||||
* ability to insert nulls. This is so because `null` is used as a special
|
||||
* return value by various methods to indicated that the double-ended queue is
|
||||
* empty.
|
||||
*
|
||||
* @template T
|
||||
* @extends QueueInterface<T>
|
||||
*/
|
||||
interface DoubleEndedQueueInterface extends QueueInterface
|
||||
{
|
||||
/**
|
||||
* Inserts the specified element at the front of this queue if it is
|
||||
* possible to do so immediately without violating capacity restrictions.
|
||||
*
|
||||
* When using a capacity-restricted double-ended queue, it is generally
|
||||
* preferable to use the `offerFirst()` method.
|
||||
*
|
||||
* @param T $element The element to add to the front of this queue.
|
||||
*
|
||||
* @return bool `true` if this queue changed as a result of the call.
|
||||
*
|
||||
* @throws RuntimeException if a queue refuses to add a particular element
|
||||
* for any reason other than that it already contains the element.
|
||||
* Implementations should use a more-specific exception that extends
|
||||
* `\RuntimeException`.
|
||||
*/
|
||||
public function addFirst(mixed $element): bool;
|
||||
|
||||
/**
|
||||
* Inserts the specified element at the end of this queue if it is possible
|
||||
* to do so immediately without violating capacity restrictions.
|
||||
*
|
||||
* When using a capacity-restricted double-ended queue, it is generally
|
||||
* preferable to use the `offerLast()` method.
|
||||
*
|
||||
* This method is equivalent to `add()`.
|
||||
*
|
||||
* @param T $element The element to add to the end of this queue.
|
||||
*
|
||||
* @return bool `true` if this queue changed as a result of the call.
|
||||
*
|
||||
* @throws RuntimeException if a queue refuses to add a particular element
|
||||
* for any reason other than that it already contains the element.
|
||||
* Implementations should use a more-specific exception that extends
|
||||
* `\RuntimeException`.
|
||||
*/
|
||||
public function addLast(mixed $element): bool;
|
||||
|
||||
/**
|
||||
* Inserts the specified element at the front of this queue if it is
|
||||
* possible to do so immediately without violating capacity restrictions.
|
||||
*
|
||||
* When using a capacity-restricted queue, this method is generally
|
||||
* preferable to `addFirst()`, which can fail to insert an element only by
|
||||
* throwing an exception.
|
||||
*
|
||||
* @param T $element The element to add to the front of this queue.
|
||||
*
|
||||
* @return bool `true` if the element was added to this queue, else `false`.
|
||||
*/
|
||||
public function offerFirst(mixed $element): bool;
|
||||
|
||||
/**
|
||||
* Inserts the specified element at the end of this queue if it is possible
|
||||
* to do so immediately without violating capacity restrictions.
|
||||
*
|
||||
* When using a capacity-restricted queue, this method is generally
|
||||
* preferable to `addLast()` which can fail to insert an element only by
|
||||
* throwing an exception.
|
||||
*
|
||||
* @param T $element The element to add to the end of this queue.
|
||||
*
|
||||
* @return bool `true` if the element was added to this queue, else `false`.
|
||||
*/
|
||||
public function offerLast(mixed $element): bool;
|
||||
|
||||
/**
|
||||
* Retrieves and removes the head of this queue.
|
||||
*
|
||||
* This method differs from `pollFirst()` only in that it throws an
|
||||
* exception if this queue is empty.
|
||||
*
|
||||
* @return T the first element in this queue.
|
||||
*
|
||||
* @throws NoSuchElementException if this queue is empty.
|
||||
*/
|
||||
public function removeFirst(): mixed;
|
||||
|
||||
/**
|
||||
* Retrieves and removes the tail of this queue.
|
||||
*
|
||||
* This method differs from `pollLast()` only in that it throws an exception
|
||||
* if this queue is empty.
|
||||
*
|
||||
* @return T the last element in this queue.
|
||||
*
|
||||
* @throws NoSuchElementException if this queue is empty.
|
||||
*/
|
||||
public function removeLast(): mixed;
|
||||
|
||||
/**
|
||||
* Retrieves and removes the head of this queue, or returns `null` if this
|
||||
* queue is empty.
|
||||
*
|
||||
* @return T | null the head of this queue, or `null` if this queue is empty.
|
||||
*/
|
||||
public function pollFirst(): mixed;
|
||||
|
||||
/**
|
||||
* Retrieves and removes the tail of this queue, or returns `null` if this
|
||||
* queue is empty.
|
||||
*
|
||||
* @return T | null the tail of this queue, or `null` if this queue is empty.
|
||||
*/
|
||||
public function pollLast(): mixed;
|
||||
|
||||
/**
|
||||
* Retrieves, but does not remove, the head of this queue.
|
||||
*
|
||||
* This method differs from `peekFirst()` only in that it throws an
|
||||
* exception if this queue is empty.
|
||||
*
|
||||
* @return T the head of this queue.
|
||||
*
|
||||
* @throws NoSuchElementException if this queue is empty.
|
||||
*/
|
||||
public function firstElement(): mixed;
|
||||
|
||||
/**
|
||||
* Retrieves, but does not remove, the tail of this queue.
|
||||
*
|
||||
* This method differs from `peekLast()` only in that it throws an exception
|
||||
* if this queue is empty.
|
||||
*
|
||||
* @return T the tail of this queue.
|
||||
*
|
||||
* @throws NoSuchElementException if this queue is empty.
|
||||
*/
|
||||
public function lastElement(): mixed;
|
||||
|
||||
/**
|
||||
* Retrieves, but does not remove, the head of this queue, or returns `null`
|
||||
* if this queue is empty.
|
||||
*
|
||||
* @return T | null the head of this queue, or `null` if this queue is empty.
|
||||
*/
|
||||
public function peekFirst(): mixed;
|
||||
|
||||
/**
|
||||
* Retrieves, but does not remove, the tail of this queue, or returns `null`
|
||||
* if this queue is empty.
|
||||
*
|
||||
* @return T | null the tail of this queue, or `null` if this queue is empty.
|
||||
*/
|
||||
public function peekLast(): mixed;
|
||||
}
|
21
vendor/ramsey/collection/src/Exception/CollectionException.php
vendored
Normal file
21
vendor/ramsey/collection/src/Exception/CollectionException.php
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the ramsey/collection library
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>
|
||||
* @license http://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ramsey\Collection\Exception;
|
||||
|
||||
use Throwable;
|
||||
|
||||
interface CollectionException extends Throwable
|
||||
{
|
||||
}
|
24
vendor/ramsey/collection/src/Exception/CollectionMismatchException.php
vendored
Normal file
24
vendor/ramsey/collection/src/Exception/CollectionMismatchException.php
vendored
Normal file
@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the ramsey/collection library
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>
|
||||
* @license http://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ramsey\Collection\Exception;
|
||||
|
||||
use RuntimeException;
|
||||
|
||||
/**
|
||||
* Thrown when attempting to operate on collections of differing types.
|
||||
*/
|
||||
class CollectionMismatchException extends RuntimeException implements CollectionException
|
||||
{
|
||||
}
|
24
vendor/ramsey/collection/src/Exception/InvalidArgumentException.php
vendored
Normal file
24
vendor/ramsey/collection/src/Exception/InvalidArgumentException.php
vendored
Normal file
@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the ramsey/collection library
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>
|
||||
* @license http://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ramsey\Collection\Exception;
|
||||
|
||||
use InvalidArgumentException as PhpInvalidArgumentException;
|
||||
|
||||
/**
|
||||
* Thrown to indicate an argument is not of the expected type.
|
||||
*/
|
||||
class InvalidArgumentException extends PhpInvalidArgumentException implements CollectionException
|
||||
{
|
||||
}
|
26
vendor/ramsey/collection/src/Exception/InvalidPropertyOrMethod.php
vendored
Normal file
26
vendor/ramsey/collection/src/Exception/InvalidPropertyOrMethod.php
vendored
Normal file
@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the ramsey/collection library
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>
|
||||
* @license http://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ramsey\Collection\Exception;
|
||||
|
||||
use RuntimeException;
|
||||
|
||||
/**
|
||||
* Thrown when attempting to evaluate a property, method, or array key
|
||||
* that doesn't exist on an element or cannot otherwise be evaluated in the
|
||||
* current context.
|
||||
*/
|
||||
class InvalidPropertyOrMethod extends RuntimeException implements CollectionException
|
||||
{
|
||||
}
|
24
vendor/ramsey/collection/src/Exception/NoSuchElementException.php
vendored
Normal file
24
vendor/ramsey/collection/src/Exception/NoSuchElementException.php
vendored
Normal file
@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the ramsey/collection library
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>
|
||||
* @license http://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ramsey\Collection\Exception;
|
||||
|
||||
use RuntimeException;
|
||||
|
||||
/**
|
||||
* Thrown when attempting to access an element that does not exist.
|
||||
*/
|
||||
class NoSuchElementException extends RuntimeException implements CollectionException
|
||||
{
|
||||
}
|
24
vendor/ramsey/collection/src/Exception/OutOfBoundsException.php
vendored
Normal file
24
vendor/ramsey/collection/src/Exception/OutOfBoundsException.php
vendored
Normal file
@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the ramsey/collection library
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>
|
||||
* @license http://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ramsey\Collection\Exception;
|
||||
|
||||
use OutOfBoundsException as PhpOutOfBoundsException;
|
||||
|
||||
/**
|
||||
* Thrown when attempting to access an element out of the range of the collection.
|
||||
*/
|
||||
class OutOfBoundsException extends PhpOutOfBoundsException implements CollectionException
|
||||
{
|
||||
}
|
24
vendor/ramsey/collection/src/Exception/UnsupportedOperationException.php
vendored
Normal file
24
vendor/ramsey/collection/src/Exception/UnsupportedOperationException.php
vendored
Normal file
@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the ramsey/collection library
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>
|
||||
* @license http://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ramsey\Collection\Exception;
|
||||
|
||||
use RuntimeException;
|
||||
|
||||
/**
|
||||
* Thrown to indicate that the requested operation is not supported.
|
||||
*/
|
||||
class UnsupportedOperationException extends RuntimeException implements CollectionException
|
||||
{
|
||||
}
|
24
vendor/ramsey/collection/src/GenericArray.php
vendored
Normal file
24
vendor/ramsey/collection/src/GenericArray.php
vendored
Normal file
@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the ramsey/collection library
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>
|
||||
* @license http://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ramsey\Collection;
|
||||
|
||||
/**
|
||||
* `GenericArray` represents a standard array object.
|
||||
*
|
||||
* @extends AbstractArray<mixed>
|
||||
*/
|
||||
class GenericArray extends AbstractArray
|
||||
{
|
||||
}
|
203
vendor/ramsey/collection/src/Map/AbstractMap.php
vendored
Normal file
203
vendor/ramsey/collection/src/Map/AbstractMap.php
vendored
Normal file
@ -0,0 +1,203 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the ramsey/collection library
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>
|
||||
* @license http://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ramsey\Collection\Map;
|
||||
|
||||
use Ramsey\Collection\AbstractArray;
|
||||
use Ramsey\Collection\Exception\InvalidArgumentException;
|
||||
use Traversable;
|
||||
|
||||
use function array_key_exists;
|
||||
use function array_keys;
|
||||
use function in_array;
|
||||
use function var_export;
|
||||
|
||||
/**
|
||||
* This class provides a basic implementation of `MapInterface`, to minimize the
|
||||
* effort required to implement this interface.
|
||||
*
|
||||
* @template K of array-key
|
||||
* @template T
|
||||
* @extends AbstractArray<T>
|
||||
* @implements MapInterface<K, T>
|
||||
*/
|
||||
abstract class AbstractMap extends AbstractArray implements MapInterface
|
||||
{
|
||||
/**
|
||||
* @param array<K, T> $data The initial items to add to this map.
|
||||
*/
|
||||
public function __construct(array $data = [])
|
||||
{
|
||||
parent::__construct($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Traversable<K, T>
|
||||
*/
|
||||
public function getIterator(): Traversable
|
||||
{
|
||||
return parent::getIterator();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param K $offset The offset to set
|
||||
* @param T $value The value to set at the given offset.
|
||||
*
|
||||
* @inheritDoc
|
||||
* @psalm-suppress MoreSpecificImplementedParamType,DocblockTypeContradiction
|
||||
*/
|
||||
public function offsetSet(mixed $offset, mixed $value): void
|
||||
{
|
||||
if ($offset === null) {
|
||||
throw new InvalidArgumentException(
|
||||
'Map elements are key/value pairs; a key must be provided for '
|
||||
. 'value ' . var_export($value, true),
|
||||
);
|
||||
}
|
||||
|
||||
$this->data[$offset] = $value;
|
||||
}
|
||||
|
||||
public function containsKey(int | string $key): bool
|
||||
{
|
||||
return array_key_exists($key, $this->data);
|
||||
}
|
||||
|
||||
public function containsValue(mixed $value): bool
|
||||
{
|
||||
return in_array($value, $this->data, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function keys(): array
|
||||
{
|
||||
return array_keys($this->data);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param K $key The key to return from the map.
|
||||
* @param T | null $defaultValue The default value to use if `$key` is not found.
|
||||
*
|
||||
* @return T | null the value or `null` if the key could not be found.
|
||||
*/
|
||||
public function get(int | string $key, mixed $defaultValue = null): mixed
|
||||
{
|
||||
return $this[$key] ?? $defaultValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param K $key The key to put or replace in the map.
|
||||
* @param T $value The value to store at `$key`.
|
||||
*
|
||||
* @return T | null the previous value associated with key, or `null` if
|
||||
* there was no mapping for `$key`.
|
||||
*/
|
||||
public function put(int | string $key, mixed $value): mixed
|
||||
{
|
||||
$previousValue = $this->get($key);
|
||||
$this[$key] = $value;
|
||||
|
||||
return $previousValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param K $key The key to put in the map.
|
||||
* @param T $value The value to store at `$key`.
|
||||
*
|
||||
* @return T | null the previous value associated with key, or `null` if
|
||||
* there was no mapping for `$key`.
|
||||
*/
|
||||
public function putIfAbsent(int | string $key, mixed $value): mixed
|
||||
{
|
||||
$currentValue = $this->get($key);
|
||||
|
||||
if ($currentValue === null) {
|
||||
$this[$key] = $value;
|
||||
}
|
||||
|
||||
return $currentValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param K $key The key to remove from the map.
|
||||
*
|
||||
* @return T | null the previous value associated with key, or `null` if
|
||||
* there was no mapping for `$key`.
|
||||
*/
|
||||
public function remove(int | string $key): mixed
|
||||
{
|
||||
$previousValue = $this->get($key);
|
||||
unset($this[$key]);
|
||||
|
||||
return $previousValue;
|
||||
}
|
||||
|
||||
public function removeIf(int | string $key, mixed $value): bool
|
||||
{
|
||||
if ($this->get($key) === $value) {
|
||||
unset($this[$key]);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param K $key The key to replace.
|
||||
* @param T $value The value to set at `$key`.
|
||||
*
|
||||
* @return T | null the previous value associated with key, or `null` if
|
||||
* there was no mapping for `$key`.
|
||||
*/
|
||||
public function replace(int | string $key, mixed $value): mixed
|
||||
{
|
||||
$currentValue = $this->get($key);
|
||||
|
||||
if ($this->containsKey($key)) {
|
||||
$this[$key] = $value;
|
||||
}
|
||||
|
||||
return $currentValue;
|
||||
}
|
||||
|
||||
public function replaceIf(int | string $key, mixed $oldValue, mixed $newValue): bool
|
||||
{
|
||||
if ($this->get($key) === $oldValue) {
|
||||
$this[$key] = $newValue;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<K, T>
|
||||
*/
|
||||
public function __serialize(): array
|
||||
{
|
||||
return parent::__serialize();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<K, T>
|
||||
*/
|
||||
public function toArray(): array
|
||||
{
|
||||
return parent::toArray();
|
||||
}
|
||||
}
|
60
vendor/ramsey/collection/src/Map/AbstractTypedMap.php
vendored
Normal file
60
vendor/ramsey/collection/src/Map/AbstractTypedMap.php
vendored
Normal file
@ -0,0 +1,60 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the ramsey/collection library
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>
|
||||
* @license http://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ramsey\Collection\Map;
|
||||
|
||||
use Ramsey\Collection\Exception\InvalidArgumentException;
|
||||
use Ramsey\Collection\Tool\TypeTrait;
|
||||
use Ramsey\Collection\Tool\ValueToStringTrait;
|
||||
|
||||
/**
|
||||
* This class provides a basic implementation of `TypedMapInterface`, to
|
||||
* minimize the effort required to implement this interface.
|
||||
*
|
||||
* @template K of array-key
|
||||
* @template T
|
||||
* @extends AbstractMap<K, T>
|
||||
* @implements TypedMapInterface<K, T>
|
||||
*/
|
||||
abstract class AbstractTypedMap extends AbstractMap implements TypedMapInterface
|
||||
{
|
||||
use TypeTrait;
|
||||
use ValueToStringTrait;
|
||||
|
||||
/**
|
||||
* @param K $offset
|
||||
* @param T $value
|
||||
*
|
||||
* @inheritDoc
|
||||
* @psalm-suppress MoreSpecificImplementedParamType
|
||||
*/
|
||||
public function offsetSet(mixed $offset, mixed $value): void
|
||||
{
|
||||
if ($this->checkType($this->getKeyType(), $offset) === false) {
|
||||
throw new InvalidArgumentException(
|
||||
'Key must be of type ' . $this->getKeyType() . '; key is '
|
||||
. $this->toolValueToString($offset),
|
||||
);
|
||||
}
|
||||
|
||||
if ($this->checkType($this->getValueType(), $value) === false) {
|
||||
throw new InvalidArgumentException(
|
||||
'Value must be of type ' . $this->getValueType() . '; value is '
|
||||
. $this->toolValueToString($value),
|
||||
);
|
||||
}
|
||||
|
||||
parent::offsetSet($offset, $value);
|
||||
}
|
||||
}
|
24
vendor/ramsey/collection/src/Map/AssociativeArrayMap.php
vendored
Normal file
24
vendor/ramsey/collection/src/Map/AssociativeArrayMap.php
vendored
Normal file
@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the ramsey/collection library
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>
|
||||
* @license http://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ramsey\Collection\Map;
|
||||
|
||||
/**
|
||||
* `AssociativeArrayMap` represents a standard associative array object.
|
||||
*
|
||||
* @extends AbstractMap<string, mixed>
|
||||
*/
|
||||
class AssociativeArrayMap extends AbstractMap
|
||||
{
|
||||
}
|
142
vendor/ramsey/collection/src/Map/MapInterface.php
vendored
Normal file
142
vendor/ramsey/collection/src/Map/MapInterface.php
vendored
Normal file
@ -0,0 +1,142 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the ramsey/collection library
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>
|
||||
* @license http://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ramsey\Collection\Map;
|
||||
|
||||
use Ramsey\Collection\ArrayInterface;
|
||||
|
||||
/**
|
||||
* An object that maps keys to values.
|
||||
*
|
||||
* A map cannot contain duplicate keys; each key can map to at most one value.
|
||||
*
|
||||
* @template K of array-key
|
||||
* @template T
|
||||
* @extends ArrayInterface<T>
|
||||
*/
|
||||
interface MapInterface extends ArrayInterface
|
||||
{
|
||||
/**
|
||||
* Returns `true` if this map contains a mapping for the specified key.
|
||||
*
|
||||
* @param K $key The key to check in the map.
|
||||
*/
|
||||
public function containsKey(int | string $key): bool;
|
||||
|
||||
/**
|
||||
* Returns `true` if this map maps one or more keys to the specified value.
|
||||
*
|
||||
* This performs a strict type check on the value.
|
||||
*
|
||||
* @param T $value The value to check in the map.
|
||||
*/
|
||||
public function containsValue(mixed $value): bool;
|
||||
|
||||
/**
|
||||
* Return an array of the keys contained in this map.
|
||||
*
|
||||
* @return list<K>
|
||||
*/
|
||||
public function keys(): array;
|
||||
|
||||
/**
|
||||
* Returns the value to which the specified key is mapped, `null` if this
|
||||
* map contains no mapping for the key, or (optionally) `$defaultValue` if
|
||||
* this map contains no mapping for the key.
|
||||
*
|
||||
* @param K $key The key to return from the map.
|
||||
* @param T | null $defaultValue The default value to use if `$key` is not found.
|
||||
*
|
||||
* @return T | null the value or `null` if the key could not be found.
|
||||
*/
|
||||
public function get(int | string $key, mixed $defaultValue = null): mixed;
|
||||
|
||||
/**
|
||||
* Associates the specified value with the specified key in this map.
|
||||
*
|
||||
* If the map previously contained a mapping for the key, the old value is
|
||||
* replaced by the specified value.
|
||||
*
|
||||
* @param K $key The key to put or replace in the map.
|
||||
* @param T $value The value to store at `$key`.
|
||||
*
|
||||
* @return T | null the previous value associated with key, or `null` if
|
||||
* there was no mapping for `$key`.
|
||||
*/
|
||||
public function put(int | string $key, mixed $value): mixed;
|
||||
|
||||
/**
|
||||
* Associates the specified value with the specified key in this map only if
|
||||
* it is not already set.
|
||||
*
|
||||
* If there is already a value associated with `$key`, this returns that
|
||||
* value without replacing it.
|
||||
*
|
||||
* @param K $key The key to put in the map.
|
||||
* @param T $value The value to store at `$key`.
|
||||
*
|
||||
* @return T | null the previous value associated with key, or `null` if
|
||||
* there was no mapping for `$key`.
|
||||
*/
|
||||
public function putIfAbsent(int | string $key, mixed $value): mixed;
|
||||
|
||||
/**
|
||||
* Removes the mapping for a key from this map if it is present.
|
||||
*
|
||||
* @param K $key The key to remove from the map.
|
||||
*
|
||||
* @return T | null the previous value associated with key, or `null` if
|
||||
* there was no mapping for `$key`.
|
||||
*/
|
||||
public function remove(int | string $key): mixed;
|
||||
|
||||
/**
|
||||
* Removes the entry for the specified key only if it is currently mapped to
|
||||
* the specified value.
|
||||
*
|
||||
* This performs a strict type check on the value.
|
||||
*
|
||||
* @param K $key The key to remove from the map.
|
||||
* @param T $value The value to match.
|
||||
*
|
||||
* @return bool true if the value was removed.
|
||||
*/
|
||||
public function removeIf(int | string $key, mixed $value): bool;
|
||||
|
||||
/**
|
||||
* Replaces the entry for the specified key only if it is currently mapped
|
||||
* to some value.
|
||||
*
|
||||
* @param K $key The key to replace.
|
||||
* @param T $value The value to set at `$key`.
|
||||
*
|
||||
* @return T | null the previous value associated with key, or `null` if
|
||||
* there was no mapping for `$key`.
|
||||
*/
|
||||
public function replace(int | string $key, mixed $value): mixed;
|
||||
|
||||
/**
|
||||
* Replaces the entry for the specified key only if currently mapped to the
|
||||
* specified value.
|
||||
*
|
||||
* This performs a strict type check on the value.
|
||||
*
|
||||
* @param K $key The key to remove from the map.
|
||||
* @param T $oldValue The value to match.
|
||||
* @param T $newValue The value to use as a replacement.
|
||||
*
|
||||
* @return bool true if the value was replaced.
|
||||
*/
|
||||
public function replaceIf(int | string $key, mixed $oldValue, mixed $newValue): bool;
|
||||
}
|
110
vendor/ramsey/collection/src/Map/NamedParameterMap.php
vendored
Normal file
110
vendor/ramsey/collection/src/Map/NamedParameterMap.php
vendored
Normal file
@ -0,0 +1,110 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the ramsey/collection library
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>
|
||||
* @license http://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ramsey\Collection\Map;
|
||||
|
||||
use Ramsey\Collection\Exception\InvalidArgumentException;
|
||||
use Ramsey\Collection\Tool\TypeTrait;
|
||||
use Ramsey\Collection\Tool\ValueToStringTrait;
|
||||
|
||||
use function array_combine;
|
||||
use function array_key_exists;
|
||||
use function is_int;
|
||||
|
||||
/**
|
||||
* `NamedParameterMap` represents a mapping of values to a set of named keys
|
||||
* that may optionally be typed
|
||||
*
|
||||
* @extends AbstractMap<string, mixed>
|
||||
*/
|
||||
class NamedParameterMap extends AbstractMap
|
||||
{
|
||||
use TypeTrait;
|
||||
use ValueToStringTrait;
|
||||
|
||||
/**
|
||||
* Named parameters defined for this map.
|
||||
*
|
||||
* @var array<string, string>
|
||||
*/
|
||||
private readonly array $namedParameters;
|
||||
|
||||
/**
|
||||
* Constructs a new `NamedParameterMap`.
|
||||
*
|
||||
* @param array<array-key, string> $namedParameters The named parameters defined for this map.
|
||||
* @param array<string, mixed> $data An initial set of data to set on this map.
|
||||
*/
|
||||
public function __construct(array $namedParameters, array $data = [])
|
||||
{
|
||||
$this->namedParameters = $this->filterNamedParameters($namedParameters);
|
||||
parent::__construct($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns named parameters set for this `NamedParameterMap`.
|
||||
*
|
||||
* @return array<string, string>
|
||||
*/
|
||||
public function getNamedParameters(): array
|
||||
{
|
||||
return $this->namedParameters;
|
||||
}
|
||||
|
||||
public function offsetSet(mixed $offset, mixed $value): void
|
||||
{
|
||||
if (!array_key_exists($offset, $this->namedParameters)) {
|
||||
throw new InvalidArgumentException(
|
||||
'Attempting to set value for unconfigured parameter \''
|
||||
. $this->toolValueToString($offset) . '\'',
|
||||
);
|
||||
}
|
||||
|
||||
if ($this->checkType($this->namedParameters[$offset], $value) === false) {
|
||||
throw new InvalidArgumentException(
|
||||
'Value for \'' . $offset . '\' must be of type '
|
||||
. $this->namedParameters[$offset] . '; value is '
|
||||
. $this->toolValueToString($value),
|
||||
);
|
||||
}
|
||||
|
||||
$this->data[$offset] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given an array of named parameters, constructs a proper mapping of
|
||||
* named parameters to types.
|
||||
*
|
||||
* @param array<array-key, string> $namedParameters The named parameters to filter.
|
||||
*
|
||||
* @return array<string, string>
|
||||
*/
|
||||
protected function filterNamedParameters(array $namedParameters): array
|
||||
{
|
||||
$names = [];
|
||||
$types = [];
|
||||
|
||||
foreach ($namedParameters as $key => $value) {
|
||||
if (is_int($key)) {
|
||||
$names[] = $value;
|
||||
$types[] = 'mixed';
|
||||
} else {
|
||||
$names[] = $key;
|
||||
$types[] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
return array_combine($names, $types) ?: [];
|
||||
}
|
||||
}
|
112
vendor/ramsey/collection/src/Map/TypedMap.php
vendored
Normal file
112
vendor/ramsey/collection/src/Map/TypedMap.php
vendored
Normal file
@ -0,0 +1,112 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the ramsey/collection library
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>
|
||||
* @license http://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ramsey\Collection\Map;
|
||||
|
||||
/**
|
||||
* A `TypedMap` represents a map of elements where key and value are typed.
|
||||
*
|
||||
* Each element is identified by a key with defined type and a value of defined
|
||||
* type. The keys of the map must be unique. The values on the map can be
|
||||
* repeated but each with its own different key.
|
||||
*
|
||||
* The most common case is to use a string type key, but it's not limited to
|
||||
* this type of keys.
|
||||
*
|
||||
* This is a direct implementation of `TypedMapInterface`, provided for the sake
|
||||
* of convenience.
|
||||
*
|
||||
* Example usage:
|
||||
*
|
||||
* ```php
|
||||
* $map = new TypedMap('string', Foo::class);
|
||||
* $map['x'] = new Foo();
|
||||
* foreach ($map as $key => $value) {
|
||||
* // do something with $key, it will be a Foo::class
|
||||
* }
|
||||
*
|
||||
* // this will throw an exception since key must be string
|
||||
* $map[10] = new Foo();
|
||||
*
|
||||
* // this will throw an exception since value must be a Foo
|
||||
* $map['bar'] = 'bar';
|
||||
*
|
||||
* // initialize map with contents
|
||||
* $map = new TypedMap('string', Foo::class, [
|
||||
* new Foo(), new Foo(), new Foo()
|
||||
* ]);
|
||||
* ```
|
||||
*
|
||||
* It is preferable to subclass `AbstractTypedMap` to create your own typed map
|
||||
* implementation:
|
||||
*
|
||||
* ```php
|
||||
* class FooTypedMap extends AbstractTypedMap
|
||||
* {
|
||||
* public function getKeyType()
|
||||
* {
|
||||
* return 'int';
|
||||
* }
|
||||
*
|
||||
* public function getValueType()
|
||||
* {
|
||||
* return Foo::class;
|
||||
* }
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* … but you also may use the `TypedMap` class:
|
||||
*
|
||||
* ```php
|
||||
* class FooTypedMap extends TypedMap
|
||||
* {
|
||||
* public function __constructor(array $data = [])
|
||||
* {
|
||||
* parent::__construct('int', Foo::class, $data);
|
||||
* }
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* @template K of array-key
|
||||
* @template T
|
||||
* @extends AbstractTypedMap<K, T>
|
||||
*/
|
||||
class TypedMap extends AbstractTypedMap
|
||||
{
|
||||
/**
|
||||
* Constructs a map object of the specified key and value types,
|
||||
* optionally with the specified data.
|
||||
*
|
||||
* @param string $keyType The data type of the map's keys.
|
||||
* @param string $valueType The data type of the map's values.
|
||||
* @param array<K, T> $data The initial data to set for this map.
|
||||
*/
|
||||
public function __construct(
|
||||
private readonly string $keyType,
|
||||
private readonly string $valueType,
|
||||
array $data = [],
|
||||
) {
|
||||
parent::__construct($data);
|
||||
}
|
||||
|
||||
public function getKeyType(): string
|
||||
{
|
||||
return $this->keyType;
|
||||
}
|
||||
|
||||
public function getValueType(): string
|
||||
{
|
||||
return $this->valueType;
|
||||
}
|
||||
}
|
36
vendor/ramsey/collection/src/Map/TypedMapInterface.php
vendored
Normal file
36
vendor/ramsey/collection/src/Map/TypedMapInterface.php
vendored
Normal file
@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the ramsey/collection library
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>
|
||||
* @license http://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ramsey\Collection\Map;
|
||||
|
||||
/**
|
||||
* A `TypedMapInterface` represents a map of elements where key and value are
|
||||
* typed.
|
||||
*
|
||||
* @template K of array-key
|
||||
* @template T
|
||||
* @extends MapInterface<K, T>
|
||||
*/
|
||||
interface TypedMapInterface extends MapInterface
|
||||
{
|
||||
/**
|
||||
* Return the type used on the key.
|
||||
*/
|
||||
public function getKeyType(): string;
|
||||
|
||||
/**
|
||||
* Return the type forced on the values.
|
||||
*/
|
||||
public function getValueType(): string;
|
||||
}
|
148
vendor/ramsey/collection/src/Queue.php
vendored
Normal file
148
vendor/ramsey/collection/src/Queue.php
vendored
Normal file
@ -0,0 +1,148 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the ramsey/collection library
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>
|
||||
* @license http://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ramsey\Collection;
|
||||
|
||||
use Ramsey\Collection\Exception\InvalidArgumentException;
|
||||
use Ramsey\Collection\Exception\NoSuchElementException;
|
||||
use Ramsey\Collection\Tool\TypeTrait;
|
||||
use Ramsey\Collection\Tool\ValueToStringTrait;
|
||||
|
||||
use function array_key_first;
|
||||
|
||||
/**
|
||||
* This class provides a basic implementation of `QueueInterface`, to minimize
|
||||
* the effort required to implement this interface.
|
||||
*
|
||||
* @template T
|
||||
* @extends AbstractArray<T>
|
||||
* @implements QueueInterface<T>
|
||||
*/
|
||||
class Queue extends AbstractArray implements QueueInterface
|
||||
{
|
||||
use TypeTrait;
|
||||
use ValueToStringTrait;
|
||||
|
||||
/**
|
||||
* Constructs a queue object of the specified type, optionally with the
|
||||
* specified data.
|
||||
*
|
||||
* @param string $queueType The type or class name associated with this queue.
|
||||
* @param array<array-key, T> $data The initial items to store in the queue.
|
||||
*/
|
||||
public function __construct(private readonly string $queueType, array $data = [])
|
||||
{
|
||||
parent::__construct($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* Since arbitrary offsets may not be manipulated in a queue, this method
|
||||
* serves only to fulfill the `ArrayAccess` interface requirements. It is
|
||||
* invoked by other operations when adding values to the queue.
|
||||
*
|
||||
* @throws InvalidArgumentException if $value is of the wrong type.
|
||||
*/
|
||||
public function offsetSet(mixed $offset, mixed $value): void
|
||||
{
|
||||
if ($this->checkType($this->getType(), $value) === false) {
|
||||
throw new InvalidArgumentException(
|
||||
'Value must be of type ' . $this->getType() . '; value is '
|
||||
. $this->toolValueToString($value),
|
||||
);
|
||||
}
|
||||
|
||||
$this->data[] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws InvalidArgumentException if $value is of the wrong type.
|
||||
*/
|
||||
public function add(mixed $element): bool
|
||||
{
|
||||
$this[] = $element;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return T
|
||||
*
|
||||
* @throws NoSuchElementException if this queue is empty.
|
||||
*/
|
||||
public function element(): mixed
|
||||
{
|
||||
return $this->peek() ?? throw new NoSuchElementException(
|
||||
'Can\'t return element from Queue. Queue is empty.',
|
||||
);
|
||||
}
|
||||
|
||||
public function offer(mixed $element): bool
|
||||
{
|
||||
try {
|
||||
return $this->add($element);
|
||||
} catch (InvalidArgumentException) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return T | null
|
||||
*/
|
||||
public function peek(): mixed
|
||||
{
|
||||
$index = array_key_first($this->data);
|
||||
|
||||
if ($index === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $this[$index];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return T | null
|
||||
*/
|
||||
public function poll(): mixed
|
||||
{
|
||||
$index = array_key_first($this->data);
|
||||
|
||||
if ($index === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$head = $this[$index];
|
||||
unset($this[$index]);
|
||||
|
||||
return $head;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return T
|
||||
*
|
||||
* @throws NoSuchElementException if this queue is empty.
|
||||
*/
|
||||
public function remove(): mixed
|
||||
{
|
||||
return $this->poll() ?? throw new NoSuchElementException(
|
||||
'Can\'t return element from Queue. Queue is empty.',
|
||||
);
|
||||
}
|
||||
|
||||
public function getType(): string
|
||||
{
|
||||
return $this->queueType;
|
||||
}
|
||||
}
|
202
vendor/ramsey/collection/src/QueueInterface.php
vendored
Normal file
202
vendor/ramsey/collection/src/QueueInterface.php
vendored
Normal file
@ -0,0 +1,202 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the ramsey/collection library
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>
|
||||
* @license http://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ramsey\Collection;
|
||||
|
||||
use Ramsey\Collection\Exception\NoSuchElementException;
|
||||
use RuntimeException;
|
||||
|
||||
/**
|
||||
* A queue is a collection in which the entities in the collection are kept in
|
||||
* order.
|
||||
*
|
||||
* The principal operations on the queue are the addition of entities to the end
|
||||
* (tail), also known as *enqueue*, and removal of entities from the front
|
||||
* (head), also known as *dequeue*. This makes the queue a first-in-first-out
|
||||
* (FIFO) data structure.
|
||||
*
|
||||
* Besides basic array operations, queues provide additional insertion,
|
||||
* extraction, and inspection operations. Each of these methods exists in two
|
||||
* forms: one throws an exception if the operation fails, the other returns a
|
||||
* special value (either `null` or `false`, depending on the operation). The
|
||||
* latter form of the insert operation is designed specifically for use with
|
||||
* capacity-restricted `QueueInterface` implementations; in most
|
||||
* implementations, insert operations cannot fail.
|
||||
*
|
||||
* <table>
|
||||
* <caption>Summary of QueueInterface methods</caption>
|
||||
* <thead>
|
||||
* <tr>
|
||||
* <td></td>
|
||||
* <td><em>Throws exception</em></td>
|
||||
* <td><em>Returns special value</em></td>
|
||||
* </tr>
|
||||
* </thead>
|
||||
* <tbody>
|
||||
* <tr>
|
||||
* <th>Insert</th>
|
||||
* <td><code>add()</code></td>
|
||||
* <td><code>offer()</code></td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <th>Remove</th>
|
||||
* <td><code>remove()</code></td>
|
||||
* <td><code>poll()</code></td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <th>Examine</th>
|
||||
* <td><code>element()</code></td>
|
||||
* <td><code>peek()</code></td>
|
||||
* </tr>
|
||||
* </tbody>
|
||||
* </table>
|
||||
*
|
||||
* Queues typically, but do not necessarily, order elements in a FIFO
|
||||
* (first-in-first-out) manner. Among the exceptions are priority queues, which
|
||||
* order elements according to a supplied comparator, or the elements' natural
|
||||
* ordering, and LIFO queues (or stacks) which order the elements LIFO
|
||||
* (last-in-first-out). Whatever the ordering used, the head of the queue is
|
||||
* that element which would be removed by a call to remove() or poll(). In a
|
||||
* FIFO queue, all new elements are inserted at the tail of the queue. Other
|
||||
* kinds of queues may use different placement rules. Every `QueueInterface`
|
||||
* implementation must specify its ordering properties.
|
||||
*
|
||||
* The `offer()` method inserts an element if possible, otherwise returning
|
||||
* `false`. This differs from the `add()` method, which can fail to add an
|
||||
* element only by throwing an unchecked exception. The `offer()` method is
|
||||
* designed for use when failure is a normal, rather than exceptional
|
||||
* occurrence, for example, in fixed-capacity (or "bounded") queues.
|
||||
*
|
||||
* The `remove()` and `poll()` methods remove and return the head of the queue.
|
||||
* Exactly which element is removed from the queue is a function of the queue's
|
||||
* ordering policy, which differs from implementation to implementation. The
|
||||
* `remove()` and `poll()` methods differ only in their behavior when the queue
|
||||
* is empty: the `remove()` method throws an exception, while the `poll()`
|
||||
* method returns `null`.
|
||||
*
|
||||
* The `element()` and `peek()` methods return, but do not remove, the head of
|
||||
* the queue.
|
||||
*
|
||||
* `QueueInterface` implementations generally do not allow insertion of `null`
|
||||
* elements, although some implementations do not prohibit insertion of `null`.
|
||||
* Even in the implementations that permit it, `null` should not be inserted
|
||||
* into a queue, as `null` is also used as a special return value by the
|
||||
* `poll()` method to indicate that the queue contains no elements.
|
||||
*
|
||||
* @template T
|
||||
* @extends ArrayInterface<T>
|
||||
*/
|
||||
interface QueueInterface extends ArrayInterface
|
||||
{
|
||||
/**
|
||||
* Ensures that this queue contains the specified element (optional
|
||||
* operation).
|
||||
*
|
||||
* Returns `true` if this queue changed as a result of the call. (Returns
|
||||
* `false` if this queue does not permit duplicates and already contains the
|
||||
* specified element.)
|
||||
*
|
||||
* Queues that support this operation may place limitations on what elements
|
||||
* may be added to this queue. In particular, some queues will refuse to add
|
||||
* `null` elements, and others will impose restrictions on the type of
|
||||
* elements that may be added. Queue classes should clearly specify in their
|
||||
* documentation any restrictions on what elements may be added.
|
||||
*
|
||||
* If a queue refuses to add a particular element for any reason other than
|
||||
* that it already contains the element, it must throw an exception (rather
|
||||
* than returning `false`). This preserves the invariant that a queue always
|
||||
* contains the specified element after this call returns.
|
||||
*
|
||||
* @see self::offer()
|
||||
*
|
||||
* @param T $element The element to add to this queue.
|
||||
*
|
||||
* @return bool `true` if this queue changed as a result of the call.
|
||||
*
|
||||
* @throws RuntimeException if a queue refuses to add a particular element
|
||||
* for any reason other than that it already contains the element.
|
||||
* Implementations should use a more-specific exception that extends
|
||||
* `\RuntimeException`.
|
||||
*/
|
||||
public function add(mixed $element): bool;
|
||||
|
||||
/**
|
||||
* Retrieves, but does not remove, the head of this queue.
|
||||
*
|
||||
* This method differs from `peek()` only in that it throws an exception if
|
||||
* this queue is empty.
|
||||
*
|
||||
* @see self::peek()
|
||||
*
|
||||
* @return T the head of this queue.
|
||||
*
|
||||
* @throws NoSuchElementException if this queue is empty.
|
||||
*/
|
||||
public function element(): mixed;
|
||||
|
||||
/**
|
||||
* Inserts the specified element into this queue if it is possible to do so
|
||||
* immediately without violating capacity restrictions.
|
||||
*
|
||||
* When using a capacity-restricted queue, this method is generally
|
||||
* preferable to `add()`, which can fail to insert an element only by
|
||||
* throwing an exception.
|
||||
*
|
||||
* @see self::add()
|
||||
*
|
||||
* @param T $element The element to add to this queue.
|
||||
*
|
||||
* @return bool `true` if the element was added to this queue, else `false`.
|
||||
*/
|
||||
public function offer(mixed $element): bool;
|
||||
|
||||
/**
|
||||
* Retrieves, but does not remove, the head of this queue, or returns `null`
|
||||
* if this queue is empty.
|
||||
*
|
||||
* @see self::element()
|
||||
*
|
||||
* @return T | null the head of this queue, or `null` if this queue is empty.
|
||||
*/
|
||||
public function peek(): mixed;
|
||||
|
||||
/**
|
||||
* Retrieves and removes the head of this queue, or returns `null`
|
||||
* if this queue is empty.
|
||||
*
|
||||
* @see self::remove()
|
||||
*
|
||||
* @return T | null the head of this queue, or `null` if this queue is empty.
|
||||
*/
|
||||
public function poll(): mixed;
|
||||
|
||||
/**
|
||||
* Retrieves and removes the head of this queue.
|
||||
*
|
||||
* This method differs from `poll()` only in that it throws an exception if
|
||||
* this queue is empty.
|
||||
*
|
||||
* @see self::poll()
|
||||
*
|
||||
* @return T the head of this queue.
|
||||
*
|
||||
* @throws NoSuchElementException if this queue is empty.
|
||||
*/
|
||||
public function remove(): mixed;
|
||||
|
||||
/**
|
||||
* Returns the type associated with this queue.
|
||||
*/
|
||||
public function getType(): string;
|
||||
}
|
59
vendor/ramsey/collection/src/Set.php
vendored
Normal file
59
vendor/ramsey/collection/src/Set.php
vendored
Normal file
@ -0,0 +1,59 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the ramsey/collection library
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>
|
||||
* @license http://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ramsey\Collection;
|
||||
|
||||
/**
|
||||
* A set is a collection that contains no duplicate elements.
|
||||
*
|
||||
* Great care must be exercised if mutable objects are used as set elements.
|
||||
* The behavior of a set is not specified if the value of an object is changed
|
||||
* in a manner that affects equals comparisons while the object is an element in
|
||||
* the set.
|
||||
*
|
||||
* Example usage:
|
||||
*
|
||||
* ``` php
|
||||
* $foo = new \My\Foo();
|
||||
* $set = new Set(\My\Foo::class);
|
||||
*
|
||||
* $set->add($foo); // returns TRUE, the element doesn't exist
|
||||
* $set->add($foo); // returns FALSE, the element already exists
|
||||
*
|
||||
* $bar = new \My\Foo();
|
||||
* $set->add($bar); // returns TRUE, $bar !== $foo
|
||||
* ```
|
||||
*
|
||||
* @template T
|
||||
* @extends AbstractSet<T>
|
||||
*/
|
||||
class Set extends AbstractSet
|
||||
{
|
||||
/**
|
||||
* Constructs a set object of the specified type, optionally with the
|
||||
* specified data.
|
||||
*
|
||||
* @param string $setType The type or class name associated with this set.
|
||||
* @param array<array-key, T> $data The initial items to store in the set.
|
||||
*/
|
||||
public function __construct(private readonly string $setType, array $data = [])
|
||||
{
|
||||
parent::__construct($data);
|
||||
}
|
||||
|
||||
public function getType(): string
|
||||
{
|
||||
return $this->setType;
|
||||
}
|
||||
}
|
31
vendor/ramsey/collection/src/Sort.php
vendored
Normal file
31
vendor/ramsey/collection/src/Sort.php
vendored
Normal file
@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the ramsey/collection library
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>
|
||||
* @license http://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ramsey\Collection;
|
||||
|
||||
/**
|
||||
* Collection sorting
|
||||
*/
|
||||
enum Sort: string
|
||||
{
|
||||
/**
|
||||
* Sort items in a collection in ascending order.
|
||||
*/
|
||||
case Ascending = 'asc';
|
||||
|
||||
/**
|
||||
* Sort items in a collection in descending order.
|
||||
*/
|
||||
case Descending = 'desc';
|
||||
}
|
57
vendor/ramsey/collection/src/Tool/TypeTrait.php
vendored
Normal file
57
vendor/ramsey/collection/src/Tool/TypeTrait.php
vendored
Normal file
@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the ramsey/collection library
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>
|
||||
* @license http://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ramsey\Collection\Tool;
|
||||
|
||||
use function is_array;
|
||||
use function is_bool;
|
||||
use function is_callable;
|
||||
use function is_float;
|
||||
use function is_int;
|
||||
use function is_numeric;
|
||||
use function is_object;
|
||||
use function is_resource;
|
||||
use function is_scalar;
|
||||
use function is_string;
|
||||
|
||||
/**
|
||||
* Provides functionality to check values for specific types.
|
||||
*/
|
||||
trait TypeTrait
|
||||
{
|
||||
/**
|
||||
* Returns `true` if value is of the specified type.
|
||||
*
|
||||
* @param string $type The type to check the value against.
|
||||
* @param mixed $value The value to check.
|
||||
*/
|
||||
protected function checkType(string $type, mixed $value): bool
|
||||
{
|
||||
return match ($type) {
|
||||
'array' => is_array($value),
|
||||
'bool', 'boolean' => is_bool($value),
|
||||
'callable' => is_callable($value),
|
||||
'float', 'double' => is_float($value),
|
||||
'int', 'integer' => is_int($value),
|
||||
'null' => $value === null,
|
||||
'numeric' => is_numeric($value),
|
||||
'object' => is_object($value),
|
||||
'resource' => is_resource($value),
|
||||
'scalar' => is_scalar($value),
|
||||
'string' => is_string($value),
|
||||
'mixed' => true,
|
||||
default => $value instanceof $type,
|
||||
};
|
||||
}
|
||||
}
|
81
vendor/ramsey/collection/src/Tool/ValueExtractorTrait.php
vendored
Normal file
81
vendor/ramsey/collection/src/Tool/ValueExtractorTrait.php
vendored
Normal file
@ -0,0 +1,81 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the ramsey/collection library
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>
|
||||
* @license http://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ramsey\Collection\Tool;
|
||||
|
||||
use Ramsey\Collection\Exception\InvalidPropertyOrMethod;
|
||||
use Ramsey\Collection\Exception\UnsupportedOperationException;
|
||||
|
||||
use function is_array;
|
||||
use function is_object;
|
||||
use function method_exists;
|
||||
use function property_exists;
|
||||
use function sprintf;
|
||||
|
||||
/**
|
||||
* Provides functionality to extract the value of a property or method from an object.
|
||||
*/
|
||||
trait ValueExtractorTrait
|
||||
{
|
||||
/**
|
||||
* Extracts the value of the given property, method, or array key from the
|
||||
* element.
|
||||
*
|
||||
* If `$propertyOrMethod` is `null`, we return the element as-is.
|
||||
*
|
||||
* @param mixed $element The element to extract the value from.
|
||||
* @param string | null $propertyOrMethod The property or method for which the
|
||||
* value should be extracted.
|
||||
*
|
||||
* @return mixed the value extracted from the specified property, method,
|
||||
* or array key, or the element itself.
|
||||
*
|
||||
* @throws InvalidPropertyOrMethod
|
||||
* @throws UnsupportedOperationException
|
||||
*/
|
||||
protected function extractValue(mixed $element, ?string $propertyOrMethod): mixed
|
||||
{
|
||||
if ($propertyOrMethod === null) {
|
||||
return $element;
|
||||
}
|
||||
|
||||
if (!is_object($element) && !is_array($element)) {
|
||||
throw new UnsupportedOperationException(sprintf(
|
||||
'The collection type "%s" does not support the $propertyOrMethod parameter',
|
||||
$this->getType(),
|
||||
));
|
||||
}
|
||||
|
||||
if (is_array($element)) {
|
||||
return $element[$propertyOrMethod] ?? throw new InvalidPropertyOrMethod(sprintf(
|
||||
'Key or index "%s" not found in collection elements',
|
||||
$propertyOrMethod,
|
||||
));
|
||||
}
|
||||
|
||||
if (property_exists($element, $propertyOrMethod)) {
|
||||
return $element->$propertyOrMethod;
|
||||
}
|
||||
|
||||
if (method_exists($element, $propertyOrMethod)) {
|
||||
return $element->{$propertyOrMethod}();
|
||||
}
|
||||
|
||||
throw new InvalidPropertyOrMethod(sprintf(
|
||||
'Method or property "%s" not defined in %s',
|
||||
$propertyOrMethod,
|
||||
$element::class,
|
||||
));
|
||||
}
|
||||
}
|
91
vendor/ramsey/collection/src/Tool/ValueToStringTrait.php
vendored
Normal file
91
vendor/ramsey/collection/src/Tool/ValueToStringTrait.php
vendored
Normal file
@ -0,0 +1,91 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the ramsey/collection library
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>
|
||||
* @license http://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Ramsey\Collection\Tool;
|
||||
|
||||
use DateTimeInterface;
|
||||
|
||||
use function assert;
|
||||
use function get_resource_type;
|
||||
use function is_array;
|
||||
use function is_bool;
|
||||
use function is_callable;
|
||||
use function is_object;
|
||||
use function is_resource;
|
||||
use function is_scalar;
|
||||
|
||||
/**
|
||||
* Provides functionality to express a value as string
|
||||
*/
|
||||
trait ValueToStringTrait
|
||||
{
|
||||
/**
|
||||
* Returns a string representation of the value.
|
||||
*
|
||||
* - null value: `'NULL'`
|
||||
* - boolean: `'TRUE'`, `'FALSE'`
|
||||
* - array: `'Array'`
|
||||
* - scalar: converted-value
|
||||
* - resource: `'(type resource #number)'`
|
||||
* - object with `__toString()`: result of `__toString()`
|
||||
* - object DateTime: ISO 8601 date
|
||||
* - object: `'(className Object)'`
|
||||
* - anonymous function: same as object
|
||||
*
|
||||
* @param mixed $value the value to return as a string.
|
||||
*/
|
||||
protected function toolValueToString(mixed $value): string
|
||||
{
|
||||
// null
|
||||
if ($value === null) {
|
||||
return 'NULL';
|
||||
}
|
||||
|
||||
// boolean constants
|
||||
if (is_bool($value)) {
|
||||
return $value ? 'TRUE' : 'FALSE';
|
||||
}
|
||||
|
||||
// array
|
||||
if (is_array($value)) {
|
||||
return 'Array';
|
||||
}
|
||||
|
||||
// scalar types (integer, float, string)
|
||||
if (is_scalar($value)) {
|
||||
return (string) $value;
|
||||
}
|
||||
|
||||
// resource
|
||||
if (is_resource($value)) {
|
||||
return '(' . get_resource_type($value) . ' resource #' . (int) $value . ')';
|
||||
}
|
||||
|
||||
// From here, $value should be an object.
|
||||
assert(is_object($value));
|
||||
|
||||
// __toString() is implemented
|
||||
if (is_callable([$value, '__toString'])) {
|
||||
return (string) $value->__toString();
|
||||
}
|
||||
|
||||
// object of type \DateTime
|
||||
if ($value instanceof DateTimeInterface) {
|
||||
return $value->format('c');
|
||||
}
|
||||
|
||||
// unknown type
|
||||
return '(' . $value::class . ' Object)';
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user