Skip to content

Commit 2de7510

Browse files
committed
allow to define results for EnumMap::key() and EnumMap::current()
1 parent c6dbe97 commit 2de7510

File tree

2 files changed

+100
-13
lines changed

2 files changed

+100
-13
lines changed

src/MabeEnum/EnumMap.php

Lines changed: 84 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,20 @@
88
class EnumMap extends SplObjectStorage
99
{
1010

11-
public function __construct($enumClass)
11+
const KEY_AS_INDEX = 1;
12+
const KEY_AS_NAME = 2;
13+
const KEY_AS_VALUE = 3;
14+
const KEY_AS_ORDINAL = 4;
15+
const CURRENT_AS_ENUM = 8;
16+
const CURRENT_AS_DATA = 16;
17+
const CURRENT_AS_NAME = 24;
18+
const CURRENT_AS_VALUE = 56;
19+
const CURRENT_AS_ORDINAL = 120;
20+
21+
private $enumClass;
22+
private $flags;
23+
24+
public function __construct($enumClass, $flags = null)
1225
{
1326
if (!is_subclass_of($enumClass, __NAMESPACE__ . '\Enum')) {
1427
throw new InvalidArgumentException(sprintf(
@@ -17,6 +30,42 @@ public function __construct($enumClass)
1730
));
1831
}
1932
$this->enumClass = $enumClass;
33+
34+
if ($flags === null) {
35+
$flags = self::KEY_AS_INDEX | self::CURRENT_AS_ENUM;
36+
}
37+
$this->setFlags($flags);
38+
}
39+
40+
public function getEnumClass()
41+
{
42+
return $this->enumClass;
43+
}
44+
45+
public function setFlags($flags)
46+
{
47+
$flags = (int)$flags;
48+
49+
$keyFlags = $flags & 7;
50+
if ($keyFlags < 1 || $keyFlags > 4) {
51+
throw new InvalidArgumentException(
52+
"Flags have to contain one of the 'KEY_AS_*' constants"
53+
);
54+
}
55+
56+
$currentFlags = $flags & 120;
57+
if ($currentFlags < 8 || $currentFlags > 120) {
58+
throw new InvalidArgumentException(
59+
"Flags have to contain one of the 'CURRENT_AS_*' constants"
60+
);
61+
}
62+
63+
$this->flags = $flags;
64+
}
65+
66+
public function getFlags()
67+
{
68+
return $this->flags;
2069
}
2170

2271
public function attach($enum, $data = null)
@@ -89,4 +138,38 @@ private function initEnum(&$enum)
89138
$this->enumClass
90139
));
91140
}
141+
142+
public function current()
143+
{
144+
switch ($this->flags & 120) {
145+
case self::CURRENT_AS_ENUM:
146+
return parent::current();
147+
case self::CURRENT_AS_DATA:
148+
return parent::getInfo();
149+
case self::CURRENT_AS_VALUE:
150+
return parent::current()->getValue();
151+
default:
152+
throw new RuntimeException(
153+
'Invalid current flags'
154+
);
155+
}
156+
}
157+
158+
public function key()
159+
{
160+
switch ($this->flags & 7) {
161+
case self::KEY_AS_INDEX:
162+
return parent::key();
163+
case self::KEY_AS_NAME:
164+
return parent::current()->getName();
165+
case self::KEY_AS_VALUE:
166+
return parent::current()->getValue();
167+
case self::KEY_AS_ORDINAL:
168+
return parent::current()->getOrdinal();
169+
default:
170+
throw new RuntimeException(
171+
'Invalid key flags'
172+
);
173+
}
174+
}
92175
}

tests/MabeEnumTest/EnumMapTest.php

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -81,32 +81,36 @@ public function testIterate()
8181
$value2 = 'value2';
8282

8383
// an empty enum map needs to be invalid, starting by 0
84+
$enumMap->rewind();
8485
$this->assertSame(0, $enumMap->count());
8586
$this->assertFalse($enumMap->valid());
8687

87-
// attach in revert order shouldn't change ordering of iteration
88-
$enumMap->attach($enum2, $value2);
89-
$enumMap->attach($enum1, $value1);
88+
// attach
89+
$enumMap->attach($enum1, $value2);
90+
$enumMap->attach($enum2, $value1);
9091

9192
// a not empty enum map should be valid, starting by 0 (if not iterated)
93+
$enumMap->rewind();
9294
$this->assertSame(2, $enumMap->count());
9395
$this->assertTrue($enumMap->valid());
94-
$this->assertSame(0, $enumMap->currentPosition());
95-
$this->assertSame($enum1, $enumMap->key());
96-
$this->assertSame($value1, $enumMap->current());
96+
$this->assertSame(0, $enumMap->key());
97+
$this->assertSame($enum1, $enumMap->current());
9798

9899
// go to the next element (last)
99100
$this->assertNull($enumMap->next());
100101
$this->assertTrue($enumMap->valid());
101-
$this->assertSame(1, $enumMap->currentPosition());
102-
$this->assertSame($enum2, $enumMap->key());
103-
$this->assertSame($value2, $enumMap->current());
102+
$this->assertSame(1, $enumMap->key());
103+
$this->assertSame($enum2, $enumMap->current());
104104

105105
// go to the next element (out of range)
106106
$this->assertNull($enumMap->next());
107107
$this->assertFalse($enumMap->valid());
108-
$this->assertSame(2, $enumMap->currentPosition());
109-
//$this->assertSame($enum2, $enumMap->currentEnum());
110-
//$this->assertSame($value2, $enumMap->currentValue());
108+
$this->assertSame(2, $enumMap->key());
109+
110+
// rewind will set the iterator position back to 0
111+
$enumMap->rewind();
112+
$this->assertTrue($enumMap->valid());
113+
$this->assertSame(0, $enumMap->key());
114+
$this->assertSame($enum1, $enumMap->current());
111115
}
112116
}

0 commit comments

Comments
 (0)