-
Notifications
You must be signed in to change notification settings - Fork 3
/
Dictionary.php
140 lines (121 loc) · 3.62 KB
/
Dictionary.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
<?php
declare(strict_types=1);
namespace Dhii\Container;
use ArrayIterator;
use Dhii\Collection\WritableContainerInterface;
use Dhii\Collection\WritableMapInterface;
use Dhii\Container\Exception\NotFoundException;
use Dhii\Container\Util\StringTranslatingTrait;
use IteratorAggregate;
use RangeException;
use Traversable;
/**
* A simple mutable dictionary, i.e. an enumerable key-value map.
*/
class Dictionary implements
IteratorAggregate,
WritableMapInterface
{
use StringTranslatingTrait;
/** @var array<array-key, mixed> */
protected $data;
/**
* @param array<array-key, mixed> $data The key-value map of data.
*/
public function __construct(array $data)
{
$this->data = $data;
}
/**
* {@inheritDoc}
*/
public function get(string $key)
{
if (!array_key_exists($key, $this->data)) {
throw new NotFoundException(
$this->__('Dictionary does not have key "%1$s"', [$key]),
0,
null
);
}
return $this->data[$key];
}
/**
* {@inheritDoc}
*/
public function has(string $key): bool
{
$isHas = array_key_exists($key, $this->data);
return $isHas;
}
/**
* {@inheritDoc}
*/
public function getIterator(): Traversable
{
return new ArrayIterator($this->data);
}
/**
* @inheritDoc
* @psalm-suppress MoreSpecificReturnType
* Psalm complains that the declared return type is more specific than inferred.
* This is not true, as it promises to return the interface.
*/
public function withMappings(array $mappings): WritableContainerInterface
{
$dictionary = $this->cloneMe();
$dictionary->data = $mappings;
/**
* @psalm-suppress LessSpecificReturnStatement
* Looks like this needs to be suppressed until able to hint return type `self`.
*/
return $dictionary;
}
/**
* @inheritDoc
* @psalm-suppress MoreSpecificReturnType
* Psalm complains that the declared return type is more specific than inferred.
* This is not true, as it promises to return the interface.
*/
public function withAddedMappings(array $mappings): WritableContainerInterface
{
$dictionary = $this->cloneMe();
$dictionary->data = $mappings + $this->data;
/**
* @psalm-suppress LessSpecificReturnStatement
* Looks like this needs to be suppressed until able to hint return type `self`.
*/
return $dictionary;
}
/**
* @inheritDoc
* @psalm-suppress MoreSpecificReturnType
* Psalm complains that the declared return type is more specific than inferred.
* This is not true, as it promises to return the interface.
*/
public function withoutKeys(array $keys): WritableContainerInterface
{
$dictionary = $this->cloneMe();
foreach ($keys as $i => $key) {
/** @psalm-suppress DocblockTypeContradiction Still want to enforce string */
if (!is_string($key)) {
throw new RangeException($this->__('Key at index %1$d is not a string', [$i]));
}
unset($dictionary->data[$key]);
}
/**
* @psalm-suppress LessSpecificReturnStatement
* Looks like this needs to be suppressed until able to hint return type `self`.
*/
return $dictionary;
}
/**
* Creates a copy of this instance
*
* @return Dictionary The new instance
*/
protected function cloneMe(): Dictionary
{
return clone $this;
}
}