Skip to content

Commit 502fd07

Browse files
authored
Merge pull request #5 from WonderNetwork/feature/floats
add floats to array accessor
2 parents 025a906 + 9837263 commit 502fd07

File tree

3 files changed

+83
-9
lines changed

3 files changed

+83
-9
lines changed

src/Accessor/ArrayAccessor.php

+41
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,22 @@ function ($value, $key) {
9292
);
9393
}
9494

95+
/**
96+
* @return float[]
97+
*/
98+
public function allFloat(): array {
99+
return map(
100+
$this->payload,
101+
function ($value, $key) {
102+
try {
103+
return StringValue::of($value)->toFloat();
104+
} catch (StringValueException $e) {
105+
$this->throw("Value at $key is not a float");
106+
}
107+
},
108+
);
109+
}
110+
95111
/**
96112
* @return bool[]
97113
*/
@@ -158,6 +174,31 @@ public function maybeInt(string $name): ?int {
158174
}
159175
}
160176

177+
public function float(string $name, float $default = 0.0): float {
178+
return $this->maybeFloat($name) ?? $default;
179+
}
180+
181+
public function requireFloat(string $name): float {
182+
$raw = $this->maybeFloat($name);
183+
if (null === $raw) {
184+
$this->throw("Required field named $name not found");
185+
}
186+
return $raw;
187+
}
188+
189+
public function maybeFloat(string $name): ?float {
190+
$raw = $this->payload[$name] ?? null;
191+
if (null === $raw) {
192+
return null;
193+
}
194+
195+
try {
196+
return StringValue::of($raw)->toFloat();
197+
} catch (StringValueException $e) {
198+
$this->throw("Required field named $name is not a float");
199+
}
200+
}
201+
161202
public function bool(string $name, bool $default = false): bool {
162203
return $this->maybeBool($name) ?? $default;
163204
}

src/Accessor/StringValue.php

+12
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,18 @@ public function toInt(): int {
4848
return (int) $this->value;
4949
}
5050

51+
public function toFloat(): float {
52+
if (is_float($this->raw) || is_int($this->raw)) {
53+
return (float) $this->raw;
54+
}
55+
56+
if (false === is_numeric($this->value)) {
57+
throw new StringValueException('Can’t convert non-numeric value to a float');
58+
}
59+
60+
return (float) $this->value;
61+
}
62+
5163
/**
5264
* @throws StringValueException
5365
*/

tests/Accessor/ArrayAccessorTest.php

+30-9
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ public function testStringOfBoolean(): void {
4343
}
4444

4545
public function testStringBailsOnArray(): void {
46-
self::expectException(ArrayAccessorException::class);
46+
$this->expectException(ArrayAccessorException::class);
4747
ArrayAccessor::of(['foo' => ['a', 'b']])->string('foo');
4848
}
4949
// endregion
@@ -76,19 +76,19 @@ public function testMaybeStringOfBoolean(): void {
7676
}
7777

7878
public function testMaybeStringBailsOnArray(): void {
79-
self::expectException(ArrayAccessorException::class);
79+
$this->expectException(ArrayAccessorException::class);
8080
ArrayAccessor::of(['foo' => ['a', 'b']])->maybeString('foo');
8181
}
8282
// endregion
8383

8484
// region requireString
8585
public function testRequireStringBailsNoKey(): void {
86-
self::expectException(ArrayAccessorException::class);
86+
$this->expectException(ArrayAccessorException::class);
8787
ArrayAccessor::of([])->requireString('foo');
8888
}
8989

9090
public function testRequireStringBailsOnNull(): void {
91-
self::expectException(ArrayAccessorException::class);
91+
$this->expectException(ArrayAccessorException::class);
9292
ArrayAccessor::of(['foo' => null])->requireString('foo');
9393
}
9494

@@ -107,7 +107,7 @@ public function testRequireStringOfBoolean(): void {
107107
}
108108

109109
public function testRequireStringBailsOnArray(): void {
110-
self::expectException(ArrayAccessorException::class);
110+
$this->expectException(ArrayAccessorException::class);
111111
ArrayAccessor::of(['foo' => ['a', 'b']])->requireString('foo');
112112
}
113113
// endregion
@@ -128,11 +128,32 @@ public function testIntCastsBoolean(): void {
128128
}
129129

130130
public function testIntBailsOnInvalidString(): void {
131-
self::expectException(ArrayAccessorException::class);
131+
$this->expectException(ArrayAccessorException::class);
132132
ArrayAccessor::of(['foo' => "bar"])->int("foo");
133133
}
134134
// endregion
135135

136+
// region float
137+
public function testFloatCastsString(): void {
138+
self::assertSame(
139+
1.0,
140+
ArrayAccessor::of(['foo' => "1"])->float("foo"),
141+
);
142+
}
143+
144+
public function testFloatCastsStringWithDotForDecimalSeparator(): void {
145+
self::assertSame(
146+
1.123,
147+
ArrayAccessor::of(['foo' => "1.123"])->float("foo"),
148+
);
149+
}
150+
151+
public function testFloatBailsOnInvalidString(): void {
152+
$this->expectException(ArrayAccessorException::class);
153+
ArrayAccessor::of(['foo' => "bar"])->float("foo");
154+
}
155+
// endregion
156+
136157
// region bool
137158
public function testBoolCastsStringTrue(): void {
138159
self::assertTrue(
@@ -159,12 +180,12 @@ public function testBoolCastsIntFalse(): void {
159180
}
160181

161182
public function testBoolBailsOnOtherNumbers(): void {
162-
self::expectException(ArrayAccessorException::class);
183+
$this->expectException(ArrayAccessorException::class);
163184
ArrayAccessor::of(['foo' => 10])->bool("foo");
164185
}
165186

166187
public function testBoolBailsOnInvalidString(): void {
167-
self::expectException(ArrayAccessorException::class);
188+
$this->expectException(ArrayAccessorException::class);
168189
ArrayAccessor::of(['foo' => "bar"])->bool("foo");
169190
}
170191
// endregion
@@ -198,7 +219,7 @@ public function testMaybeAt(): void {
198219
}
199220

200221
public function testMaybeAtBailsOnStringKey(): void {
201-
self::expectException(ArrayAccessorException::class);
222+
$this->expectException(ArrayAccessorException::class);
202223
ArrayAccessor::of(['weekdays' => 'string'])->maybeAt('weekdays');
203224
}
204225

0 commit comments

Comments
 (0)