Skip to content

Commit 9bac7aa

Browse files
committed
extracted ArrayList from CypherList
1 parent 274159f commit 9bac7aa

File tree

2 files changed

+255
-219
lines changed

2 files changed

+255
-219
lines changed

src/Types/ArrayList.php

Lines changed: 253 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,253 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/*
6+
* This file is part of the Laudis Neo4j package.
7+
*
8+
* (c) Laudis technologies <http://laudis.tech>
9+
*
10+
* For the full copyright and license information, please view the LICENSE
11+
* file that was distributed with this source code.
12+
*/
13+
14+
namespace Laudis\Neo4j\Types;
15+
16+
use function array_key_exists;
17+
use function array_key_last;
18+
use function array_slice;
19+
use function is_int;
20+
use Laudis\Neo4j\Exception\RuntimeTypeException;
21+
use Laudis\Neo4j\TypeCaster;
22+
use OutOfBoundsException;
23+
use function sort;
24+
use function usort;
25+
26+
/**
27+
* An immutable ordered sequence of items.
28+
*
29+
* @template TValue
30+
*
31+
* @extends AbstractCypherSequence<int, TValue>
32+
*
33+
* @psalm-immutable
34+
*/
35+
class ArrayList extends AbstractCypherSequence
36+
{
37+
/**
38+
* @param iterable<TValue> $iterable
39+
*/
40+
final public function __construct(iterable $iterable = [])
41+
{
42+
if ($iterable instanceof self) {
43+
/** @psalm-suppress InvalidPropertyAssignmentValue */
44+
$this->sequence = $iterable->sequence;
45+
} else {
46+
$this->sequence = [];
47+
foreach ($iterable as $value) {
48+
$this->sequence[] = $value;
49+
}
50+
}
51+
}
52+
53+
/**
54+
* Returns the first element in the sequence.
55+
*
56+
* @return TValue
57+
*/
58+
public function first()
59+
{
60+
if (!array_key_exists(0, $this->sequence)) {
61+
throw new OutOfBoundsException('Cannot grab first element of an empty list');
62+
}
63+
64+
return $this->sequence[0];
65+
}
66+
67+
/**
68+
* Returns the last element in the sequence.
69+
*
70+
* @return TValue
71+
*/
72+
public function last()
73+
{
74+
$key = array_key_last($this->sequence);
75+
if (!is_int($key)) {
76+
throw new OutOfBoundsException('Cannot grab last element of an empty list');
77+
}
78+
79+
return $this->sequence[$key];
80+
}
81+
82+
/**
83+
* @param iterable<TValue> $values
84+
*
85+
* @return static<TValue>
86+
*/
87+
public function merge($values): ArrayList
88+
{
89+
$tbr = $this->sequence;
90+
foreach ($values as $value) {
91+
$tbr[] = $value;
92+
}
93+
94+
return static::fromIterable($tbr);
95+
}
96+
97+
/**
98+
* @return static<TValue>
99+
*/
100+
public function reversed(): ArrayList
101+
{
102+
return static::fromIterable(array_reverse($this->sequence));
103+
}
104+
105+
/**
106+
* @return static<TValue>
107+
*/
108+
public function slice(int $offset, int $length = null): ArrayList
109+
{
110+
return static::fromIterable(array_slice($this->sequence, $offset, $length));
111+
}
112+
113+
/**
114+
* @param (pure-callable(TValue, TValue):int)|null $comparator
115+
*
116+
* @return static<TValue>
117+
*/
118+
public function sorted(callable $comparator = null): ArrayList
119+
{
120+
$tbr = $this->sequence;
121+
if ($comparator === null) {
122+
sort($tbr);
123+
} else {
124+
usort($tbr, $comparator);
125+
}
126+
127+
return static::fromIterable($tbr);
128+
}
129+
130+
/**
131+
* @pure
132+
*/
133+
public static function fromIterable(iterable $iterable): AbstractCypherSequence
134+
{
135+
return new static($iterable);
136+
}
137+
138+
/**
139+
* Gets the nth element in the list.
140+
*
141+
* @throws OutOfBoundsException
142+
*
143+
* @return TValue
144+
*/
145+
public function get(int $key)
146+
{
147+
if (!array_key_exists($key, $this->sequence)) {
148+
throw new OutOfBoundsException(sprintf('Cannot get item in sequence at position: %s', $key));
149+
}
150+
151+
return $this->sequence[$key];
152+
}
153+
154+
public function getAsString(int $key): string
155+
{
156+
$value = $this->get($key);
157+
$tbr = TypeCaster::toString($value);
158+
if ($tbr === null) {
159+
throw new RuntimeTypeException($value, 'string');
160+
}
161+
162+
return $tbr;
163+
}
164+
165+
public function getAsInt(int $key): int
166+
{
167+
$value = $this->get($key);
168+
$tbr = TypeCaster::toInt($value);
169+
if ($tbr === null) {
170+
throw new RuntimeTypeException($value, 'int');
171+
}
172+
173+
return $tbr;
174+
}
175+
176+
public function getAsFloat(int $key): float
177+
{
178+
$value = $this->get($key);
179+
$tbr = TypeCaster::toFloat($value);
180+
if ($tbr === null) {
181+
throw new RuntimeTypeException($value, 'float');
182+
}
183+
184+
return $tbr;
185+
}
186+
187+
public function getAsBool(int $key): bool
188+
{
189+
$value = $this->get($key);
190+
$tbr = TypeCaster::toBool($value);
191+
if ($tbr === null) {
192+
throw new RuntimeTypeException($value, 'bool');
193+
}
194+
195+
return $tbr;
196+
}
197+
198+
/**
199+
* @return null
200+
*/
201+
public function getAsNull(int $key)
202+
{
203+
$this->get($key);
204+
205+
return TypeCaster::toNull();
206+
}
207+
208+
/**
209+
* @template U
210+
*
211+
* @param class-string<U> $class
212+
*
213+
* @return U
214+
*/
215+
public function getAsObject(int $key, string $class): object
216+
{
217+
$value = $this->get($key);
218+
$tbr = TypeCaster::toClass($value, $class);
219+
if ($tbr === null) {
220+
throw new RuntimeTypeException($value, $class);
221+
}
222+
223+
return $tbr;
224+
}
225+
226+
/**
227+
* @return CypherMap<mixed>
228+
*/
229+
public function getAsCypherMap(int $key): CypherMap
230+
{
231+
$value = $this->get($key);
232+
$tbr = TypeCaster::toCypherMap($value);
233+
if ($tbr === null) {
234+
throw new RuntimeTypeException($value, CypherMap::class);
235+
}
236+
237+
return $tbr;
238+
}
239+
240+
/**
241+
* @return CypherList<mixed>
242+
*/
243+
public function getAsCypherList(int $key): CypherList
244+
{
245+
$value = $this->get($key);
246+
$tbr = TypeCaster::toCypherList($value);
247+
if ($tbr === null) {
248+
throw new RuntimeTypeException($value, CypherList::class);
249+
}
250+
251+
return $tbr;
252+
}
253+
}

0 commit comments

Comments
 (0)