Add ArrayClass and ImmutableArrayClass

2.x 1.0.0
Julien Rosset 3 years ago
parent a998bf9de1
commit b8dc4c2e79

@ -1,3 +1,3 @@
# PhpArrayClass # PhpArrayClasses
Classes for array embedding Classes for array embedding

@ -1,5 +1,5 @@
{ {
"name": "jrosset/arrayclass", "name": "jrosset/arrayclasses",
"description": "Classes for array embedding", "description": "Classes for array embedding",
"keywords": [ ], "keywords": [ ],

@ -0,0 +1,61 @@
<?php
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;
}
/**
* 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);
}
}

@ -0,0 +1,15 @@
<?php
namespace jrosset\ArrayClasses;
/**
* Interface for PHP-native array cast
*/
interface IArrayCast {
/**
* Transform to a PHP-native array
*
* @return array The native array
*/
public function toArray (): array;
}

@ -0,0 +1,182 @@
<?php
namespace jrosset\ArrayClasses;
use ArrayAccess;
use ArrayIterator;
use Countable;
use InvalidArgumentException;
use IteratorAggregate;
use JsonSerializable;
use OutOfRangeException;
use Serializable;
use Traversable;
/**
* An immutable array
*/
class ImmutableArrayClass implements IteratorAggregate, JsonSerializable, Serializable, Countable, ArrayAccess, IArrayCast {
/**
* @var array The internal array
*/
protected array $array;
/**
* @var bool Throws an exception for nonexistent elements ?
*/
private bool $throwsForNonExistentElement;
/**
* 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);
}
}
/**
* 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);
}
/**
* 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);
}
/**
* @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,11 @@
<?php
namespace jrosset\ArrayClasses;
use LogicException;
/**
* Exception thrown when trying to modify an immutable element
*/
class ImmutableException extends LogicException {
}
Loading…
Cancel
Save