diff --git a/src/ArrayClasses/ArrayClass.php b/src/ArrayClasses/ArrayClass.php index a32b610..88b3ef5 100644 --- a/src/ArrayClasses/ArrayClass.php +++ b/src/ArrayClasses/ArrayClass.php @@ -2,60 +2,16 @@ namespace jrosset\ArrayClasses; -use OutOfRangeException; - /** * An array */ -class ArrayClass extends ImmutableArrayClass { - /** - * Set or replace a cell value - * - * @param mixed $offset The cell offset - * @param mixed $value The cell new value - * - * @return $this - */ - public function set ($offset, $value): self { - $this->array[$offset] = $value; - return $this; - } - /** - * Remove a cell - * - * @param mixed $offset The cell offset - * @param bool|null $throwsForNonExistentElement If set, temporarily override {@see ImmutableArrayClass::$throwsForNonExistentElement} - * - * @return $this - */ - public function del ($offset, ?bool $throwsForNonExistentElement = null): self { - if ($throwsForNonExistentElement ?? $this->throwsForNonExistentElement() && !$this->has($offset)) { - throw new OutOfRangeException(); - } - unset($this->array[$offset]); - - return $this; - } +class ArrayClass extends ImmutableArrayClass implements IArrayClass { + use TInternalArray; - /** - * Create an immutable copy - * - * @return ImmutableArrayClass The immutable copy - */ - public function toImmutableArrayClass (): ImmutableArrayClass { - return new ImmutableArrayClass($this); - } - - /** - * @inheritDoc - */ - public function offsetSet ($offset, $value): void { - $this->set($offset, $value); - } /** * @inheritDoc */ - public function offsetUnset ($offset): void { - $this->del($offset); + public function toImmutable (): IImmutableArrayClass { + return new ImmutableArrayClass($this->array, $this->throwsForNonExistentElement()); } } \ No newline at end of file diff --git a/src/ArrayClasses/IArrayClass.php b/src/ArrayClasses/IArrayClass.php new file mode 100644 index 0000000..4971443 --- /dev/null +++ b/src/ArrayClasses/IArrayClass.php @@ -0,0 +1,30 @@ +setThrowsForNonExistentElement($throwsForNonExistentElement); - - if (is_array($initial)) { - $this->array = $initial; - } - elseif (is_null($initial)) { - $this->array = []; - } - elseif ($initial instanceof IArrayCast) { - $this->array = $initial->toArray(); - } - else { - throw new InvalidArgumentException('The initial value is not valid: null, array or ' . IArrayCast::class); - } - } - /** - * Get the value of a cell - * - * @param mixed $offset The cell offset - * - * @return mixed|null The cell value - */ - public function __invoke ($offset) { - return $this->get($offset); - } - /** - * Set information to dump - * - * @return array The information to dump - * - * @see https://www.php.net/manual/function.var-dump.php - */ - public function __debugInfo (): array { - return [ - 'array' => $this->array, - ]; - } - - /** - * Check if a cell offset exists - * - * @param mixed $offset The cell offset - * - * @return bool True if the cell offset exists - */ - public function has ($offset): bool { - return array_key_exists($offset, $this->array); - } - /** - * Get the value of a cell - * - * @param mixed $offset The cell offset - * @param bool|null $throwsForNonExistentElement If set, temporarily override {@see ImmutableArrayClass::$throwsForNonExistentElement} - * - * @return mixed|null The cell value - */ - public function get ($offset, ?bool $throwsForNonExistentElement = null) { - if ($this->has($offset)) { - return $this->array[$offset]; - } - if ($throwsForNonExistentElement ?? $this->throwsForNonExistentElement()) { - throw new OutOfRangeException(); - } - return null; - } - - /** - * @inheritDoc - */ - public function toArray (): array { - return $this->array; - } - /** - * Create a mutable copy - * - * @return ArrayClass The mutable copy - */ - public function toMutableArrayClass (): ArrayClass { - return new ArrayClass($this); - } - - /** - * @inheritDoc - */ - public function count (): int { - return count($this->array); - } - - /** - * @inheritDoc - */ - public function getIterator (): Traversable { - return new ArrayIterator($this->array); - } +class ImmutableArrayClass implements IImmutableArrayClass { + use TImmutableInternalArray; /** * @inheritDoc */ - public function offsetExists ($offset): bool { - return $this->has($offset); - } - /** - * @inheritDoc - */ - public function offsetGet ($offset) { - return $this->get($offset); - } - /** - * @inheritDoc - */ - public function offsetSet ($offset, $value): void { - throw new ImmutableException(); - } - /** - * @inheritDoc - */ - public function offsetUnset ($offset): void { - throw new ImmutableException(); - } - - /** - * @inheritDoc - */ - public function serialize (): string { - return serialize($this->array); - } - /** - * @inheritDoc - */ - public function unserialize ($data): void { - $this->array = unserialize($data); - } - - /** - * @inheritDoc - */ - public function jsonSerialize () { - return $this->array; - } - - /** - * Throws an exception for nonexistent elements ? - * - * @return bool Throws an exception for nonexistent elements ? - */ - public function throwsForNonExistentElement (): bool { - return $this->throwsForNonExistentElement; - } - /** - * Set if throws an exception for nonexistent elements - * - * @param bool $throwsForNonExistentElement Throws an exception for nonexistent elements ? - * - * @return $this - */ - public function setThrowsForNonExistentElement (bool $throwsForNonExistentElement): self { - $this->throwsForNonExistentElement = $throwsForNonExistentElement; - return $this; + public function toMutable (): IArrayClass { + return new ArrayClass($this->array, $this->throwsForNonExistentElement()); } } \ No newline at end of file diff --git a/src/ArrayClasses/TImmutableInternalArray.php b/src/ArrayClasses/TImmutableInternalArray.php new file mode 100644 index 0000000..0ec0e8d --- /dev/null +++ b/src/ArrayClasses/TImmutableInternalArray.php @@ -0,0 +1,168 @@ +setThrowsForNonExistentElement($throwsForNonExistentElement); + + if (is_array($initial)) { + $this->array = $initial; + } + elseif (is_null($initial)) { + $this->array = []; + } + elseif ($initial instanceof IArrayCast) { + $this->array = $initial->toArray(); + } + else { + throw new InvalidArgumentException('The initial value is not valid: null, array or ' . IArrayCast::class); + } + } + /** + * Set information to dump + * + * @return array The information to dump + * + * @see https://www.php.net/manual/function.var-dump.php + */ + public function __debugInfo (): array { + return [ + 'array' => $this->array, + ]; + } + + /** + * Check if a cell offset exists + * + * @param mixed $offset The cell offset + * + * @return bool True if the cell offset exists + */ + public function has ($offset): bool { + return array_key_exists($offset, $this->array); + } + /** + * Get the value of a cell + * + * @param mixed $offset The cell offset + * @param bool|null $throwsForNonExistentElement If set, temporarily override {@see ImmutableArrayClass::$throwsForNonExistentElement} + * + * @return mixed|null The cell value + */ + public function get ($offset, ?bool $throwsForNonExistentElement = null) { + if ($this->has($offset)) { + return $this->array[$offset]; + } + if ($throwsForNonExistentElement ?? $this->throwsForNonExistentElement()) { + throw new OutOfRangeException(); + } + return null; + } + + /** + * @inheritDoc + */ + public function toArray (): array { + return $this->array; + } + + /** + * @inheritDoc + */ + public function count (): int { + return count($this->array); + } + + /** + * @inheritDoc + */ + public function getIterator (): Traversable { + return new ArrayIterator($this->array); + } + + /** + * @inheritDoc + */ + public function offsetExists ($offset): bool { + return $this->has($offset); + } + /** + * @inheritDoc + */ + public function offsetGet ($offset) { + return $this->get($offset); + } + /** + * @inheritDoc + */ + public function offsetSet ($offset, $value): void { + throw new ImmutableException(); + } + /** + * @inheritDoc + */ + public function offsetUnset ($offset): void { + throw new ImmutableException(); + } + + /** + * @inheritDoc + */ + public function serialize (): string { + return serialize($this->array); + } + /** + * @inheritDoc + */ + public function unserialize ($data): void { + $this->array = unserialize($data); + } + + /** + * @inheritDoc + */ + public function jsonSerialize () { + return $this->array; + } + + /** + * Throws an exception for nonexistent elements ? + * + * @return bool Throws an exception for nonexistent elements ? + */ + public function throwsForNonExistentElement (): bool { + return $this->throwsForNonExistentElement; + } + /** + * Set if throws an exception for nonexistent elements + * + * @param bool $throwsForNonExistentElement Throws an exception for nonexistent elements ? + * + * @return $this + */ + public function setThrowsForNonExistentElement (bool $throwsForNonExistentElement): self { + $this->throwsForNonExistentElement = $throwsForNonExistentElement; + return $this; + } +} \ No newline at end of file diff --git a/src/ArrayClasses/TInternalArray.php b/src/ArrayClasses/TInternalArray.php new file mode 100644 index 0000000..e9ba1d0 --- /dev/null +++ b/src/ArrayClasses/TInternalArray.php @@ -0,0 +1,49 @@ +array[$offset] = $value; + return $this; + } + /** + * Remove a cell + * + * @param mixed $offset The cell offset + * @param bool|null $throwsForNonExistentElement If set, temporarily override {@see ImmutableArrayClass::$throwsForNonExistentElement} + * + * @return $this + */ + public function del ($offset, ?bool $throwsForNonExistentElement = null): self { + if ($throwsForNonExistentElement ?? $this->throwsForNonExistentElement() && !$this->has($offset)) { + throw new OutOfRangeException(); + } + unset($this->array[$offset]); + + return $this; + } + + /** + * @inheritDoc + */ + public function offsetSet ($offset, $value): void { + $this->set($offset, $value); + } + /** + * @inheritDoc + */ + public function offsetUnset ($offset): void { + $this->del($offset); + } +} \ No newline at end of file