Page Menu
Home
DevCentral
Search
Configure Global Search
Log In
Files
F12460270
D3847.id9963.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
13 KB
Referenced Files
None
Subscribers
None
D3847.id9963.diff
View Options
diff --git a/omnitools/src/DataTypes/Option/None.php b/omnitools/src/DataTypes/Option/None.php
--- a/omnitools/src/DataTypes/Option/None.php
+++ b/omnitools/src/DataTypes/Option/None.php
@@ -26,7 +26,20 @@
return $this;
}
- public function orElse (mixed $default) : mixed {
+ public function or (Option $default) : Option {
return $default;
}
+
+ public function orElse (callable $callable) : Option {
+ return $callable();
+ }
+
+ public function getValueOr (mixed $default) : mixed {
+ return $default;
+ }
+
+ public function getValueOrElse (callable $callable) : mixed {
+ return $callable();
+ }
+
}
diff --git a/omnitools/src/DataTypes/Option/Option.php b/omnitools/src/DataTypes/Option/Option.php
--- a/omnitools/src/DataTypes/Option/Option.php
+++ b/omnitools/src/DataTypes/Option/Option.php
@@ -10,7 +10,40 @@
public abstract function map(callable $callable) : self;
- public abstract function orElse(mixed $default) : mixed;
+ /**
+ * Returns the option if it contains a value,
+ * otherwise returns the default option.
+ */
+ public abstract function or(Option $default) : self;
+
+ /**
+ * Returns the option if it contains a value,
+ * otherwise calls the callable and returns the result.
+ *
+ * The callable is called only on None, allowing lazy evaluation.
+ * The callable must return an Option.
+ */
+ public abstract function orElse(callable $callable) : self;
+
+ /**
+ * Returns the value of the option if it is Some,
+ * or the default value if the option is None.
+ *
+ * @param mixed $default The default value
+ * @return mixed
+ */
+ public abstract function getValueOr(mixed $default) : mixed;
+
+ /**
+ * Returns the value of the option if it is Some,
+ * or the result of the callable if the option is None.
+ *
+ * The callable is called only on None, allowing lazy evaluation.
+ *
+ * @param callable $callable A function that returns a default value.
+ * @return mixed
+ */
+ public abstract function getValueOrElse(callable $callable) : mixed;
///
/// Helper to build options
diff --git a/omnitools/src/DataTypes/Option/Some.php b/omnitools/src/DataTypes/Option/Some.php
--- a/omnitools/src/DataTypes/Option/Some.php
+++ b/omnitools/src/DataTypes/Option/Some.php
@@ -53,7 +53,19 @@
return new self($value);
}
- public function orElse (mixed $default) : mixed {
+ public function or (Option $default) : Option {
+ return $this;
+ }
+
+ public function orElse (callable $callable) : Option {
+ return $this;
+ }
+
+ public function getValueOr (mixed $default) : mixed {
+ return $this->value;
+ }
+
+ public function getValueOrElse (callable $callable) : mixed {
return $this->value;
}
}
diff --git a/omnitools/src/DataTypes/Result/Err.php b/omnitools/src/DataTypes/Result/Err.php
--- a/omnitools/src/DataTypes/Result/Err.php
+++ b/omnitools/src/DataTypes/Result/Err.php
@@ -2,13 +2,16 @@
namespace Keruald\OmniTools\DataTypes\Result;
-use Exception;
+use Keruald\OmniTools\Reflection\CallableElement;
+
use InvalidArgumentException;
use Throwable;
class Err extends Result {
private ?Throwable $error;
+ const CB_TOO_MANY_ARGS = "The callback must take 0 or 1 argument.";
+
public function __construct (Throwable $error = null) {
$this->error = $error;
}
@@ -48,7 +51,37 @@
return new self($error);
}
- public function orElse (mixed $default) : mixed {
+ public function or (Result $default) : Result {
return $default;
}
+
+ public function orElse (callable $callable) : Result {
+ $argc = (new CallableElement($callable))->countArguments();
+
+ return match($argc) {
+ 0 => $callable(),
+ 1 => $callable($this->error),
+
+ default => throw new InvalidArgumentException(
+ self::CB_TOO_MANY_ARGS, 0, $this->error
+ ),
+ };
+ }
+
+ public function getValueOr (mixed $default) : mixed {
+ return $default;
+ }
+
+ public function getValueOrElse (callable $callable) : mixed {
+ $argc = (new CallableElement($callable))->countArguments();
+
+ return match($argc) {
+ 0 => $callable(),
+ 1 => $callable($this->error),
+
+ default => throw new InvalidArgumentException(
+ self::CB_TOO_MANY_ARGS, 0, $this->error
+ ),
+ };
+ }
}
diff --git a/omnitools/src/DataTypes/Result/Ok.php b/omnitools/src/DataTypes/Result/Ok.php
--- a/omnitools/src/DataTypes/Result/Ok.php
+++ b/omnitools/src/DataTypes/Result/Ok.php
@@ -57,7 +57,19 @@
return $this;
}
- public function orElse (mixed $default) : mixed {
+ public function or (Result $default) : Result {
+ return $this;
+ }
+
+ public function orElse (callable $callable) : Result {
+ return $this;
+ }
+
+ public function getValueOr (mixed $default) : mixed {
+ return $this->value;
+ }
+
+ public function getValueOrElse (callable $callable) : mixed {
return $this->value;
}
}
diff --git a/omnitools/src/DataTypes/Result/Result.php b/omnitools/src/DataTypes/Result/Result.php
--- a/omnitools/src/DataTypes/Result/Result.php
+++ b/omnitools/src/DataTypes/Result/Result.php
@@ -11,5 +11,41 @@
public abstract function map(callable $callable) : self;
public abstract function mapErr(callable $callable): self;
- public abstract function orElse(mixed $default) : mixed;
+ /**
+ * Returns the result if it is Ok,
+ * or the default result if an Err.
+ *
+ * @param mixed $default The default value
+ * @return mixed
+ */
+ public abstract function or(Result $default) : self;
+
+ /**
+ * Returns the result if it is Ok,
+ * otherwise calls the callable and returns the new result.
+ *
+ * The callable is called only on Err, allowing lazy evaluation.
+ * The callable must return a Result.
+ */
+ public abstract function orElse(callable $callable) : self;
+
+ /**
+ * Returns the value of the result if it is Ok,
+ * or the default value if the option is Err.
+ *
+ * @param mixed $default The default value
+ * @return mixed
+ */
+ public abstract function getValueOr(mixed $default) : mixed;
+
+ /**
+ * Returns the value of the result if it is Ok,
+ * or the result of the callable if the option is Err.
+ *
+ * The callable is called only on Err, allowing lazy evaluation.
+ *
+ * @param callable $callable A function that returns a default value.
+ * @return mixed
+ */
+ public abstract function getValueOrElse(callable $callable) : mixed;
}
diff --git a/omnitools/src/Events/Propagation.php b/omnitools/src/Events/Propagation.php
--- a/omnitools/src/Events/Propagation.php
+++ b/omnitools/src/Events/Propagation.php
@@ -27,7 +27,7 @@
foreach ($callables as $callable) {
if (!is_callable($callable)) {
$previous = self::grabException($parameters);
- throw new BadFunctionCallException("Callback for this method.", 0, $previous->orElse(null));
+ throw new BadFunctionCallException("Callback for this method.", 0, $previous->getValueOr(null));
}
call_user_func_array($callable, $parameters);
@@ -49,7 +49,7 @@
public static function callOrThrow (iterable $callables, array $parameters = [], Throwable $exception = null) : void {
if (!count($callables)) {
throw $exception ?? self::grabException($parameters)
- ->orElse(new RuntimeException);
+ ->getValueOrElse(fn () => new RuntimeException);
}
static::call($callables, $parameters);
diff --git a/omnitools/tests/DataTypes/Option/NoneTest.php b/omnitools/tests/DataTypes/Option/NoneTest.php
--- a/omnitools/tests/DataTypes/Option/NoneTest.php
+++ b/omnitools/tests/DataTypes/Option/NoneTest.php
@@ -6,6 +6,7 @@
use Keruald\OmniTools\DataTypes\Option\None;
use Keruald\OmniTools\DataTypes\Option\Option;
+use Keruald\OmniTools\DataTypes\Option\Some;
use PHPUnit\Framework\TestCase;
@@ -39,8 +40,28 @@
$this->assertEquals($mapped_v, $this->v);
}
+ public function testOr () : void {
+ $actual = $this->v->or(new Some(666));
+
+ $this->assertTrue($actual->isSome());
+ $this->assertEquals(666, $actual->getValue());
+ }
+
public function testOrElse () : void {
- $value = $this->v->orElse(666);
+ $actual = $this->v->orElse(fn () => new Some(666));
+
+ $this->assertTrue($actual->isSome());
+ $this->assertEquals(666, $actual->getValue());
+ }
+
+ public function testGetValueOr () : void {
+ $value = $this->v->getValueOr(666);
+
+ $this->assertEquals(666, $value);
+ }
+
+ public function testGetValueOrElse () : void {
+ $value = $this->v->getValueOrElse(fn () => 666);
$this->assertEquals(666, $value);
}
diff --git a/omnitools/tests/DataTypes/Option/SomeTest.php b/omnitools/tests/DataTypes/Option/SomeTest.php
--- a/omnitools/tests/DataTypes/Option/SomeTest.php
+++ b/omnitools/tests/DataTypes/Option/SomeTest.php
@@ -49,8 +49,28 @@
$this->assertEquals(84, $mapped_v->getValue());
}
+ public function testOr () : void {
+ $actual = $this->v->or(new Some(666));
+
+ $this->assertTrue($actual->isSome());
+ $this->assertEquals(42, $actual->getValue());
+ }
+
public function testOrElse () : void {
- $value = $this->v->orElse(666);
+ $actual = $this->v->orElse(fn () => new Some(666));
+
+ $this->assertTrue($actual->isSome());
+ $this->assertEquals(42, $actual->getValue());
+ }
+
+ public function testGetValueOr () : void {
+ $value = $this->v->getValueOr(666);
+
+ $this->assertEquals(42, $value);
+ }
+
+ public function testGetValueOrElse () : void {
+ $value = $this->v->getValueOrElse(fn () => 666);
$this->assertEquals(42, $value);
}
diff --git a/omnitools/tests/DataTypes/Result/ErrTest.php b/omnitools/tests/DataTypes/Result/ErrTest.php
--- a/omnitools/tests/DataTypes/Result/ErrTest.php
+++ b/omnitools/tests/DataTypes/Result/ErrTest.php
@@ -5,9 +5,13 @@
use DivisionByZeroError;
use Exception;
+use InvalidArgumentException;
+use RuntimeException;
use Throwable;
use Keruald\OmniTools\DataTypes\Result\Err;
+use Keruald\OmniTools\DataTypes\Result\Ok;
+
use PHPUnit\Framework\TestCase;
class ErrTest extends TestCase {
@@ -48,9 +52,55 @@
$this->assertInstanceOf(Exception::class, $mapped_v->getError());
}
+ public function testOr () : void {
+ $actual = $this->v->or(new Ok(666));
+
+ $this->assertTrue($actual->isOk());
+ $this->assertEquals(666, $actual->getValue());
+ }
+
public function testOrElse () : void {
- $value = $this->v->orElse(666);
+ $actual = $this->v->orElse(fn () => new Ok(666));
+
+ $this->assertTrue($actual->isOk());
+ $this->assertEquals(666, $actual->getValue());
+ }
+
+ public function testOrElseWithCallbackArgument () : void {
+ $actual = $this->v->orElse(
+ fn ($error) => new Err(new RuntimeException(get_class($error)))
+ );
+
+ $this->assertTrue($actual->isError());
+ $this->assertInstanceOf(RuntimeException::class, $actual->getError());
+ $this->assertEquals("DivisionByZeroError", $actual->getError()->getMessage());
+ }
+
+ public function testOrElseWithTooManyCallbackArgument () : void {
+ $this->expectException(InvalidArgumentException::class);
+ $this->v->orElse(fn ($error, $extraneous) => get_class($error));
+ }
+
+ public function testGetValueOr () : void {
+ $value = $this->v->getValueOr(666);
+
+ $this->assertEquals(666, $value);
+ }
+
+ public function testGetValueOrElse () : void {
+ $value = $this->v->getValueOrElse(fn () => 666);
$this->assertEquals(666, $value);
}
+
+ public function testGetValueOrElseWithCallbackArgument () : void {
+ $actual = $this->v->getValueOrElse(fn ($error) => get_class($error));
+
+ $this->assertEquals("DivisionByZeroError", $actual);
+ }
+
+ public function testGetValueOrElseWithTooManyCallbackArgument () : void {
+ $this->expectException(InvalidArgumentException::class);
+ $this->v->getValueOrElse(fn ($error, $extraneous) => get_class($error));
+ }
}
diff --git a/omnitools/tests/DataTypes/Result/OkTest.php b/omnitools/tests/DataTypes/Result/OkTest.php
--- a/omnitools/tests/DataTypes/Result/OkTest.php
+++ b/omnitools/tests/DataTypes/Result/OkTest.php
@@ -57,8 +57,28 @@
$this->assertEquals($mapped_v, $this->v);
}
+ public function testOr () : void {
+ $actual = $this->v->or(new Ok(666));
+
+ $this->assertTrue($actual->isOk());
+ $this->assertEquals(42, $actual->getValue());
+ }
+
public function testOrElse () : void {
- $value = $this->v->orElse(666);
+ $actual = $this->v->orElse(fn () => new Ok(666));
+
+ $this->assertTrue($actual->isOk());
+ $this->assertEquals(42, $actual->getValue());
+ }
+
+ public function testGetValueOr () : void {
+ $value = $this->v->getValueOr(666);
+
+ $this->assertEquals(42, $value);
+ }
+
+ public function testGetValueOrElse () : void {
+ $value = $this->v->getValueOrElse(fn () => 666);
$this->assertEquals(42, $value);
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Nov 8, 05:14 (5 h, 48 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
3141236
Default Alt Text
D3847.id9963.diff (13 KB)
Attached To
Mode
D3847: Implement getValueOr, getValueOrElse, or, orElse for Result and Option
Attached
Detach File
Event Timeline
Log In to Comment