Extract interface and use trait for implementation
parent
d56366fbfb
commit
096d4bc3ed
@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace jrosset\ArrayClasses;
|
||||
|
||||
interface IArrayClass extends IImmutableArrayClass {
|
||||
/**
|
||||
* Create or replace a cell
|
||||
*
|
||||
* @param mixed $cellName The cell name/offset
|
||||
* @param mixed $cellValue The cell new value
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function set ($cellName, $cellValue): self;
|
||||
/**
|
||||
* Remove a cell
|
||||
*
|
||||
* @param mixed $cellName The cell name/offset
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function del ($cellName): self;
|
||||
|
||||
/**
|
||||
* Create an immutable copy
|
||||
*
|
||||
* @return IImmutableArrayClass The immutable copy
|
||||
*/
|
||||
public function toImmutable (): IImmutableArrayClass;
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
namespace jrosset\ArrayClasses;
|
||||
|
||||
use ArrayAccess;
|
||||
use Countable;
|
||||
use IteratorAggregate;
|
||||
use JsonSerializable;
|
||||
use Serializable;
|
||||
|
||||
interface IImmutableArrayClass extends IteratorAggregate, JsonSerializable, Serializable, Countable, ArrayAccess, IArrayCast {
|
||||
/**
|
||||
* Check if a cell exists
|
||||
*
|
||||
* @param mixed $cellName The cell name/offset
|
||||
*
|
||||
* @return bool Is the cell exists ?
|
||||
*/
|
||||
public function has ($cellName): bool;
|
||||
/**
|
||||
* Get the value of a cell
|
||||
*
|
||||
* @param mixed $cellName The cell name/offset
|
||||
*
|
||||
* @return mixed The cell value
|
||||
*/
|
||||
public function get ($cellName);
|
||||
|
||||
/**
|
||||
* Create a mutable copy
|
||||
*
|
||||
* @return IArrayClass The mutable copy
|
||||
*/
|
||||
public function toMutable (): IArrayClass;
|
||||
}
|
@ -0,0 +1,168 @@
|
||||
<?php
|
||||
|
||||
namespace jrosset\ArrayClasses;
|
||||
|
||||
use ArrayIterator;
|
||||
use InvalidArgumentException;
|
||||
use OutOfRangeException;
|
||||
use Traversable;
|
||||
|
||||
trait TImmutableInternalArray {
|
||||
/**
|
||||
* @var array The internal array
|
||||
*/
|
||||
protected array $array = [];
|
||||
/**
|
||||
* @var bool Throws an exception for nonexistent elements ?
|
||||
*/
|
||||
private bool $throwsForNonExistentElement = true;
|
||||
|
||||
/**
|
||||
* Initialize the array
|
||||
*
|
||||
* @param IArrayCast|array|null $initial The initial value
|
||||
* @param bool $throwsForNonExistentElement Throws an exception for nonexistent elements ?
|
||||
*/
|
||||
public function __construct ($initial = null, bool $throwsForNonExistentElement = true) {
|
||||
$this->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;
|
||||
}
|
||||
}
|
@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
namespace jrosset\ArrayClasses;
|
||||
|
||||
use OutOfRangeException;
|
||||
|
||||
trait TInternalArray {
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function offsetSet ($offset, $value): void {
|
||||
$this->set($offset, $value);
|
||||
}
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function offsetUnset ($offset): void {
|
||||
$this->del($offset);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue