Page MenuHomeDevCentral

D1656.diff
No OneTemporary

D1656.diff

diff --git a/omnitools/src/DataTypes/Result/Err.php b/omnitools/src/DataTypes/Result/Err.php
new file mode 100644
--- /dev/null
+++ b/omnitools/src/DataTypes/Result/Err.php
@@ -0,0 +1,54 @@
+<?php
+
+namespace Keruald\OmniTools\DataTypes\Result;
+
+use Exception;
+use InvalidArgumentException;
+use Throwable;
+
+class Err extends Result {
+ private ?Throwable $error;
+
+ public function __construct (Throwable $error = null) {
+ $this->error = $error;
+ }
+
+ public function isOK () : false {
+ return false;
+ }
+
+ public function isError () : true {
+ return true;
+ }
+
+ public function getValue () : mixed {
+ throw new InvalidArgumentException(<<<'EOD'
+This result is an error, so it doesn't have a value.
+You can check first with isOK() if this is a value.
+Or if you want the error, use getError().
+EOD
+);
+ }
+
+ public function getError () : Throwable {
+ return $this->error;
+ }
+
+ public function setError (Throwable $error) : void {
+ $this->error = $error;
+ }
+
+ public function map (callable $callable) : self {
+ return $this;
+ }
+
+ public function mapErr (callable $callable) : self {
+ $error = $callable($this->error);
+
+ return new self($error);
+ }
+
+ public function orElse (mixed $default) : mixed {
+ return $default;
+ }
+}
diff --git a/omnitools/src/DataTypes/Result/Ok.php b/omnitools/src/DataTypes/Result/Ok.php
new file mode 100644
--- /dev/null
+++ b/omnitools/src/DataTypes/Result/Ok.php
@@ -0,0 +1,72 @@
+<?php
+
+namespace Keruald\OmniTools\DataTypes\Result;
+
+use InvalidArgumentException;
+
+class Ok extends Result {
+ private mixed $value = null;
+
+ private string $type = "NULL";
+
+ public function __construct ($value = null) {
+ if ($value !== null) {
+ $this->setValue($value);
+ }
+ }
+
+ public function isOK () : true {
+ return true;
+ }
+
+ public function isError () : false {
+ return false;
+ }
+
+ public function getValue () : mixed {
+ return $this->value;
+ }
+
+ public function setValue (mixed $value) : void {
+ $type = self::getTypeOf($value);
+ if (!$this->isAcceptableValueType($type)) {
+ throw new InvalidArgumentException(<<<'EOD'
+When you mutate the value of an Ok object, you can't mutate the object type.
+Please consider return a new Ok instead.
+EOD
+ );
+ }
+
+ $this->value = $value;
+ $this->type = $type;
+ }
+
+ private function isAcceptableValueType (string $type) : bool {
+ return $this->value === null || $type === $this->type;
+ }
+
+
+ private static function getTypeOf ($v) : string {
+ $type = gettype($v);
+
+ if ($type === "object") {
+ return get_class($v);
+ }
+
+ return $type;
+ }
+
+ public function map (callable $callable) : self {
+ $value = $callable($this->value);
+
+ return new self($value);
+ }
+
+ public function mapErr (callable $callable) : self {
+ return $this;
+ }
+
+ public function orElse (mixed $default) : mixed {
+ return $this->value;
+ }
+}
diff --git a/omnitools/src/DataTypes/Result/Result.php b/omnitools/src/DataTypes/Result/Result.php
new file mode 100644
--- /dev/null
+++ b/omnitools/src/DataTypes/Result/Result.php
@@ -0,0 +1,15 @@
+<?php
+
+namespace Keruald\OmniTools\DataTypes\Result;
+
+abstract class Result {
+ public abstract function isOK () : bool;
+ public abstract function isError () : bool;
+
+ public abstract function getValue () : mixed;
+
+ public abstract function map(callable $callable) : self;
+ public abstract function mapErr(callable $callable): self;
+
+ public abstract function orElse(mixed $default) : mixed;
+}
diff --git a/omnitools/tests/DataTypes/Result/ErrTest.php b/omnitools/tests/DataTypes/Result/ErrTest.php
new file mode 100644
--- /dev/null
+++ b/omnitools/tests/DataTypes/Result/ErrTest.php
@@ -0,0 +1,56 @@
+<?php
+declare(strict_types=1);
+
+namespace Keruald\OmniTools\Tests\DataTypes\Result;
+
+use DivisionByZeroError;
+use Exception;
+use Throwable;
+
+use Keruald\OmniTools\DataTypes\Result\Err;
+use PHPUnit\Framework\TestCase;
+
+class ErrTest extends TestCase {
+ public function setUp () : void {
+ $this->v = new Err;
+ $this->v->setError(new DivisionByZeroError());
+ }
+
+ public function testIsOk () : void {
+ $this->AssertFalse($this->v->isOk());
+ }
+
+ public function testIsError () : void {
+ $this->assertTrue($this->v->isError());
+ }
+
+ public function testGetValue () : void {
+ $this->expectException("InvalidArgumentException");
+ $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 testMapErr () : void {
+ $callback = function (Throwable $ex) {
+ return new Exception();
+ };
+
+ $mapped_v = $this->v->mapErr($callback);
+ $this->assertInstanceOf(Exception::class, $mapped_v->getError());
+ }
+
+ public function testOrElse () : void {
+ $value = $this->v->orElse(666);
+
+ $this->assertEquals(666, $value);
+ }
+}
diff --git a/omnitools/tests/DataTypes/Result/OkTest.php b/omnitools/tests/DataTypes/Result/OkTest.php
new file mode 100644
--- /dev/null
+++ b/omnitools/tests/DataTypes/Result/OkTest.php
@@ -0,0 +1,65 @@
+<?php
+declare(strict_types=1);
+
+namespace Keruald\OmniTools\Tests\DataTypes\Result;
+
+use Exception;
+
+use Keruald\OmniTools\DataTypes\Result\Ok;
+use PHPUnit\Framework\TestCase;
+
+class OkTest extends TestCase {
+
+ public function setUp () : void {
+ $this->v = new Ok;
+ $this->v->setValue(42);
+ }
+
+ public function testIsOk () : void {
+ $this->AssertTrue($this->v->isOk());
+ }
+
+ public function testIsError () : void {
+ $this->assertFalse($this->v->isError());
+ }
+
+ 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");
+ $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 testMapErr () : void {
+ $callback = function (Exception $ex) {
+ return new Exception();
+ };
+
+ $mapped_v = $this->v->mapErr($callback);
+
+ $this->assertEquals($mapped_v, $this->v);
+ }
+
+ public function testOrElse () : void {
+ $value = $this->v->orElse(666);
+
+ $this->assertEquals(42, $value);
+ }
+}

File Metadata

Mime Type
text/plain
Expires
Mon, Nov 25, 02:19 (15 h, 14 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2261548
Default Alt Text
D1656.diff (7 KB)

Event Timeline