Page MenuHomeDevCentral

D3741.diff
No OneTemporary

D3741.diff

diff --git a/composer.json b/composer.json
--- a/composer.json
+++ b/composer.json
@@ -43,7 +43,7 @@
"keruald/commands": "0.0.1",
"keruald/database": "0.4.0",
"keruald/github": "0.2.1",
- "keruald/omnitools": "0.13.0",
+ "keruald/omnitools": "0.14.0",
"keruald/report": "0.1.0"
},
"autoload": {
diff --git a/omnitools/src/DataTypes/Option/None.php b/omnitools/src/DataTypes/Option/None.php
new file mode 100644
--- /dev/null
+++ b/omnitools/src/DataTypes/Option/None.php
@@ -0,0 +1,32 @@
+<?php
+
+namespace Keruald\OmniTools\DataTypes\Option;
+
+use InvalidArgumentException;
+
+class None extends Option {
+
+ public function isSome () : bool {
+ return false;
+ }
+
+ public function isNone () : bool {
+ return true;
+ }
+
+ public function getValue () : mixed {
+ throw new InvalidArgumentException(<<<'EOD'
+This option is a none, so it doesn't have a value.
+You can check first with isSome() if this is a value.
+EOD
+ );
+ }
+
+ public function map (callable $callable) : Option {
+ return $this;
+ }
+
+ public function orElse (mixed $default) : mixed {
+ return $default;
+ }
+}
diff --git a/omnitools/src/DataTypes/Option/Option.php b/omnitools/src/DataTypes/Option/Option.php
new file mode 100644
--- /dev/null
+++ b/omnitools/src/DataTypes/Option/Option.php
@@ -0,0 +1,14 @@
+<?php
+
+namespace Keruald\OmniTools\DataTypes\Option;
+
+abstract class Option {
+ public abstract function isSome () : bool;
+ public abstract function isNone () : bool;
+
+ public abstract function getValue() : mixed;
+
+ public abstract function map(callable $callable) : self;
+
+ public abstract function orElse(mixed $default) : mixed;
+}
diff --git a/omnitools/src/DataTypes/Option/Some.php b/omnitools/src/DataTypes/Option/Some.php
new file mode 100644
--- /dev/null
+++ b/omnitools/src/DataTypes/Option/Some.php
@@ -0,0 +1,59 @@
+<?php
+
+namespace Keruald\OmniTools\DataTypes\Option;
+
+use InvalidArgumentException;
+
+use Keruald\OmniTools\Reflection\Type;
+
+class Some extends Option {
+ private mixed $value = null;
+
+ private string $type = "NULL";
+
+ public function __construct ($value = null) {
+ if ($value !== null) {
+ $this->setValue($value);
+ }
+ }
+
+ public function isSome () : bool {
+ return true;
+ }
+
+ public function isNone () : bool {
+ return false;
+ }
+
+ public function getValue () : mixed {
+ return $this->value;
+ }
+
+ public function setValue (mixed $value) : void {
+ $type = Type::getTypeOf($value);
+ if (!$this->isAcceptableValueType($type)) {
+ throw new InvalidArgumentException(<<<'EOD'
+When you mutate the value of an Some object, you can't mutate the object type.
+Please consider return a new Some instead.
+EOD
+ );
+ }
+
+ $this->value = $value;
+ $this->type = $type;
+ }
+
+ private function isAcceptableValueType (string $type) : bool {
+ return $this->value === null || $type === $this->type;
+ }
+
+ public function map (callable $callable) : Option {
+ $value = $callable($this->value);
+
+ return new self($value);
+ }
+
+ public function orElse (mixed $default) : mixed {
+ return $this->value;
+ }
+}
diff --git a/omnitools/tests/DataTypes/Option/NoneTest.php b/omnitools/tests/DataTypes/Option/NoneTest.php
new file mode 100644
--- /dev/null
+++ b/omnitools/tests/DataTypes/Option/NoneTest.php
@@ -0,0 +1,47 @@
+<?php
+
+namespace Keruald\OmniTools\Tests\DataTypes\Option;
+
+use InvalidArgumentException;
+
+use Keruald\OmniTools\DataTypes\Option\None;
+use Keruald\OmniTools\DataTypes\Option\Option;
+
+use PHPUnit\Framework\TestCase;
+
+class NoneTest extends TestCase {
+ private Option $v;
+
+ public function setUp () : void {
+ $this->v = new None;
+ }
+
+ public function testIsSome () : void {
+ $this->assertFalse($this->v->isSome());
+ }
+
+ public function testIsNone () : void {
+ $this->assertTrue($this->v->isNone());
+ }
+
+ public function testGetValue () : void {
+ $this->expectException(InvalidArgumentException::class);
+ $this->v->getValue();
+ }
+
+ public function testMap () : void {
+ $callback = function ($n) {
+ return $n * 2;
+ };
+
+ $mapped_v = $this->v->map($callback);
+
+ $this->assertEquals($mapped_v, $this->v);
+ }
+
+ public function testOrElse () : void {
+ $value = $this->v->orElse(666);
+
+ $this->assertEquals(666, $value);
+ }
+}
diff --git a/omnitools/tests/DataTypes/Option/SomeTest.php b/omnitools/tests/DataTypes/Option/SomeTest.php
new file mode 100644
--- /dev/null
+++ b/omnitools/tests/DataTypes/Option/SomeTest.php
@@ -0,0 +1,57 @@
+<?php
+
+namespace Keruald\OmniTools\Tests\DataTypes\Option;
+
+use InvalidArgumentException;
+
+use Keruald\OmniTools\DataTypes\Option\Some;
+use Keruald\OmniTools\DataTypes\Option\Option;
+
+use PHPUnit\Framework\TestCase;
+
+class SomeTest extends TestCase {
+ private Option $v;
+
+ public function setUp () : void {
+ $this->v = new Some;
+ $this->v->setValue(42);
+ }
+
+ public function testIsSome () : void {
+ $this->assertTrue($this->v->isSome());
+ }
+
+ public function testIsNone () : void {
+ $this->assertFalse($this->v->isNone());
+ }
+
+ public function testGetValue () : void {
+ $this->assertEquals(42, $this->v->getValue());
+ }
+
+ public function testSetValue () : void {
+ $this->v->setValue(666);
+ $this->assertEquals(666, $this->v->getValue());
+ }
+
+ public function testSetValueWhenTypeIsMutated () : void {
+ $this->expectException(InvalidArgumentException::class);
+ $this->v->setValue("Another type");
+ }
+
+ public function testMap () : void {
+ $callback = function ($n) {
+ return $n * 2;
+ };
+
+ $mapped_v = $this->v->map($callback);
+
+ $this->assertEquals(84, $mapped_v->getValue());
+ }
+
+ public function testOrElse () : void {
+ $value = $this->v->orElse(666);
+
+ $this->assertEquals(42, $value);
+ }
+}

File Metadata

Mime Type
text/plain
Expires
Tue, Oct 14, 20:30 (21 h, 21 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
3074596
Default Alt Text
D3741.diff (6 KB)

Event Timeline