3 Commits

Author SHA1 Message Date
9327d8fa29 Update properties in README 2024-09-30 23:06:57 -04:00
483d7875d5 Change functions to properties
- Force PHP 8.4
2024-09-30 22:59:46 -04:00
6779b2c554 Restrict PHP version
- Update deps
2024-09-30 20:14:52 -04:00
8 changed files with 188 additions and 218 deletions

1
.gitignore vendored
View File

@@ -1,2 +1,3 @@
.idea .idea
vendor vendor
*.tests.txt

View File

@@ -2,6 +2,8 @@
This project contains PHP utility classes whose functionality is inspired by their F# counterparts. This project contains PHP utility classes whose functionality is inspired by their F# counterparts.
The v2 series requires at least PHP 8.4. A similar API exists for PHP 8.2 - 8.3 in version 1 of this project; see its README for specifics.
## What It Provides ## What It Provides
This early-stage library currently provides two classes, both of which are designed to wrap values and indicate the state of the action that produced them. `Option<T>` represents a variable that may or may not have a value. `Result<TOK, TError>` represents the result of an action; the "ok" and "error" states both provide a value. This early-stage library currently provides two classes, both of which are designed to wrap values and indicate the state of the action that produced them. `Option<T>` represents a variable that may or may not have a value. `Result<TOK, TError>` represents the result of an action; the "ok" and "error" states both provide a value.
@@ -11,12 +13,12 @@ This early-stage library currently provides two classes, both of which are desig
| **Creating** | `::Some(T)` for Some | `::OK(TOK)` for OK | | **Creating** | `::Some(T)` for Some | `::OK(TOK)` for OK |
| | `::None()` for None | `::Error(TError)` for Error | | | `::None()` for None | `::Error(TError)` for Error |
| | `::of($value)` _None if `null`_ | | | | `::of($value)` _None if `null`_ | |
| **Querying** | `->isSome(): bool` | `->isOK(): bool` | | **Querying** | `->isSome: bool` | `->isOK: bool` |
| | `->isNone(): bool` | `->isError(): bool` | | | `->isNone: bool` | `->isError: bool` |
| | `->contains(T, $strict = true): bool` | `->contains(TOK, $strict = true): bool` | | | `->contains(T, $strict = true): bool` | `->contains(TOK, $strict = true): bool` |
| | `->exists(callable(T): bool): bool` | `->exists(callable(TOK): bool): bool` | | | `->exists(callable(T): bool): bool` | `->exists(callable(TOK): bool): bool` |
| **Reading**<br> | `->get(): T` | `->getOK(): TOK` | | **Reading**<br> | `->value: T` | `->ok: TOK` |
| _all throw if called on missing value_ | | `->getError(): TError` | | _all throw if called on missing value_ | | `->error: TError` |
| **Transforming**<br> | `->map(callable(T): TMapped): Option<TMapped>` | `->map(callable(TOK): TMapped): Result<TMapped, TError>` | | **Transforming**<br> | `->map(callable(T): TMapped): Option<TMapped>` | `->map(callable(TOK): TMapped): Result<TMapped, TError>` |
| _all still `Option` or `Result`_ | | `->mapError(callable(TError): TMapped): Result<TOK, TMapped>` | | _all still `Option` or `Result`_ | | `->mapError(callable(TError): TMapped): Result<TOK, TMapped>` |
| **Iterating** | `->iter(callable(T): void): void` | `->iter(callable(TOK): void): void` | | **Iterating** | `->iter(callable(T): void): void` | `->iter(callable(TOK): void): void` |

View File

@@ -17,7 +17,7 @@
"rss": "https://git.bitbadger.solutions/bit-badger/inspired-by-fsharp.rss" "rss": "https://git.bitbadger.solutions/bit-badger/inspired-by-fsharp.rss"
}, },
"require": { "require": {
"php": "^8.2" "php": ">=8.4"
}, },
"require-dev": { "require-dev": {
"phpunit/phpunit": "^11", "phpunit/phpunit": "^11",

114
composer.lock generated
View File

@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "9c0a6b77d5d66ee91ab9946d5f5e2107", "content-hash": "0cd12c9ee6159a96158d62691add3401",
"packages": [], "packages": [],
"packages-dev": [ "packages-dev": [
{ {
@@ -69,16 +69,16 @@
}, },
{ {
"name": "nikic/php-parser", "name": "nikic/php-parser",
"version": "v5.1.0", "version": "v5.3.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/nikic/PHP-Parser.git", "url": "https://github.com/nikic/PHP-Parser.git",
"reference": "683130c2ff8c2739f4822ff7ac5c873ec529abd1" "reference": "3abf7425cd284141dc5d8d14a9ee444de3345d1a"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/683130c2ff8c2739f4822ff7ac5c873ec529abd1", "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/3abf7425cd284141dc5d8d14a9ee444de3345d1a",
"reference": "683130c2ff8c2739f4822ff7ac5c873ec529abd1", "reference": "3abf7425cd284141dc5d8d14a9ee444de3345d1a",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -121,9 +121,9 @@
], ],
"support": { "support": {
"issues": "https://github.com/nikic/PHP-Parser/issues", "issues": "https://github.com/nikic/PHP-Parser/issues",
"source": "https://github.com/nikic/PHP-Parser/tree/v5.1.0" "source": "https://github.com/nikic/PHP-Parser/tree/v5.3.0"
}, },
"time": "2024-07-01T20:03:41+00:00" "time": "2024-09-29T13:56:26+00:00"
}, },
{ {
"name": "phar-io/manifest", "name": "phar-io/manifest",
@@ -320,32 +320,32 @@
}, },
{ {
"name": "phpunit/php-code-coverage", "name": "phpunit/php-code-coverage",
"version": "11.0.5", "version": "11.0.6",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/sebastianbergmann/php-code-coverage.git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git",
"reference": "19b6365ab8b59a64438c0c3f4241feeb480c9861" "reference": "ebdffc9e09585dafa71b9bffcdb0a229d4704c45"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/19b6365ab8b59a64438c0c3f4241feeb480c9861", "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/ebdffc9e09585dafa71b9bffcdb0a229d4704c45",
"reference": "19b6365ab8b59a64438c0c3f4241feeb480c9861", "reference": "ebdffc9e09585dafa71b9bffcdb0a229d4704c45",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"ext-dom": "*", "ext-dom": "*",
"ext-libxml": "*", "ext-libxml": "*",
"ext-xmlwriter": "*", "ext-xmlwriter": "*",
"nikic/php-parser": "^5.0", "nikic/php-parser": "^5.1.0",
"php": ">=8.2", "php": ">=8.2",
"phpunit/php-file-iterator": "^5.0", "phpunit/php-file-iterator": "^5.0.1",
"phpunit/php-text-template": "^4.0", "phpunit/php-text-template": "^4.0.1",
"sebastian/code-unit-reverse-lookup": "^4.0", "sebastian/code-unit-reverse-lookup": "^4.0.1",
"sebastian/complexity": "^4.0", "sebastian/complexity": "^4.0.1",
"sebastian/environment": "^7.0", "sebastian/environment": "^7.2.0",
"sebastian/lines-of-code": "^3.0", "sebastian/lines-of-code": "^3.0.1",
"sebastian/version": "^5.0", "sebastian/version": "^5.0.1",
"theseer/tokenizer": "^1.2.0" "theseer/tokenizer": "^1.2.3"
}, },
"require-dev": { "require-dev": {
"phpunit/phpunit": "^11.0" "phpunit/phpunit": "^11.0"
@@ -357,7 +357,7 @@
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-main": "11.0-dev" "dev-main": "11.0.x-dev"
} }
}, },
"autoload": { "autoload": {
@@ -386,7 +386,7 @@
"support": { "support": {
"issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues",
"security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy",
"source": "https://github.com/sebastianbergmann/php-code-coverage/tree/11.0.5" "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/11.0.6"
}, },
"funding": [ "funding": [
{ {
@@ -394,20 +394,20 @@
"type": "github" "type": "github"
} }
], ],
"time": "2024-07-03T05:05:37+00:00" "time": "2024-08-22T04:37:56+00:00"
}, },
{ {
"name": "phpunit/php-file-iterator", "name": "phpunit/php-file-iterator",
"version": "5.0.1", "version": "5.1.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/sebastianbergmann/php-file-iterator.git", "url": "https://github.com/sebastianbergmann/php-file-iterator.git",
"reference": "6ed896bf50bbbfe4d504a33ed5886278c78e4a26" "reference": "118cfaaa8bc5aef3287bf315b6060b1174754af6"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/6ed896bf50bbbfe4d504a33ed5886278c78e4a26", "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/118cfaaa8bc5aef3287bf315b6060b1174754af6",
"reference": "6ed896bf50bbbfe4d504a33ed5886278c78e4a26", "reference": "118cfaaa8bc5aef3287bf315b6060b1174754af6",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -447,7 +447,7 @@
"support": { "support": {
"issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues",
"security": "https://github.com/sebastianbergmann/php-file-iterator/security/policy", "security": "https://github.com/sebastianbergmann/php-file-iterator/security/policy",
"source": "https://github.com/sebastianbergmann/php-file-iterator/tree/5.0.1" "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/5.1.0"
}, },
"funding": [ "funding": [
{ {
@@ -455,7 +455,7 @@
"type": "github" "type": "github"
} }
], ],
"time": "2024-07-03T05:06:37+00:00" "time": "2024-08-27T05:02:59+00:00"
}, },
{ {
"name": "phpunit/php-invoker", "name": "phpunit/php-invoker",
@@ -643,16 +643,16 @@
}, },
{ {
"name": "phpunit/phpunit", "name": "phpunit/phpunit",
"version": "11.2.8", "version": "11.3.6",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/sebastianbergmann/phpunit.git", "url": "https://github.com/sebastianbergmann/phpunit.git",
"reference": "a7a29e8d3113806f18f99d670f580a30e8ffff39" "reference": "d62c45a19c665bb872c2a47023a0baf41a98bb2b"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/a7a29e8d3113806f18f99d670f580a30e8ffff39", "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/d62c45a19c665bb872c2a47023a0baf41a98bb2b",
"reference": "a7a29e8d3113806f18f99d670f580a30e8ffff39", "reference": "d62c45a19c665bb872c2a47023a0baf41a98bb2b",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -666,20 +666,20 @@
"phar-io/manifest": "^2.0.4", "phar-io/manifest": "^2.0.4",
"phar-io/version": "^3.2.1", "phar-io/version": "^3.2.1",
"php": ">=8.2", "php": ">=8.2",
"phpunit/php-code-coverage": "^11.0.5", "phpunit/php-code-coverage": "^11.0.6",
"phpunit/php-file-iterator": "^5.0.1", "phpunit/php-file-iterator": "^5.1.0",
"phpunit/php-invoker": "^5.0.1", "phpunit/php-invoker": "^5.0.1",
"phpunit/php-text-template": "^4.0.1", "phpunit/php-text-template": "^4.0.1",
"phpunit/php-timer": "^7.0.1", "phpunit/php-timer": "^7.0.1",
"sebastian/cli-parser": "^3.0.2", "sebastian/cli-parser": "^3.0.2",
"sebastian/code-unit": "^3.0.1", "sebastian/code-unit": "^3.0.1",
"sebastian/comparator": "^6.0.1", "sebastian/comparator": "^6.1.0",
"sebastian/diff": "^6.0.2", "sebastian/diff": "^6.0.2",
"sebastian/environment": "^7.2.0", "sebastian/environment": "^7.2.0",
"sebastian/exporter": "^6.1.3", "sebastian/exporter": "^6.1.3",
"sebastian/global-state": "^7.0.2", "sebastian/global-state": "^7.0.2",
"sebastian/object-enumerator": "^6.0.1", "sebastian/object-enumerator": "^6.0.1",
"sebastian/type": "^5.0.1", "sebastian/type": "^5.1.0",
"sebastian/version": "^5.0.1" "sebastian/version": "^5.0.1"
}, },
"suggest": { "suggest": {
@@ -691,7 +691,7 @@
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-main": "11.2-dev" "dev-main": "11.3-dev"
} }
}, },
"autoload": { "autoload": {
@@ -723,7 +723,7 @@
"support": { "support": {
"issues": "https://github.com/sebastianbergmann/phpunit/issues", "issues": "https://github.com/sebastianbergmann/phpunit/issues",
"security": "https://github.com/sebastianbergmann/phpunit/security/policy", "security": "https://github.com/sebastianbergmann/phpunit/security/policy",
"source": "https://github.com/sebastianbergmann/phpunit/tree/11.2.8" "source": "https://github.com/sebastianbergmann/phpunit/tree/11.3.6"
}, },
"funding": [ "funding": [
{ {
@@ -739,7 +739,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2024-07-18T14:56:37+00:00" "time": "2024-09-19T10:54:28+00:00"
}, },
{ {
"name": "sebastian/cli-parser", "name": "sebastian/cli-parser",
@@ -913,16 +913,16 @@
}, },
{ {
"name": "sebastian/comparator", "name": "sebastian/comparator",
"version": "6.0.1", "version": "6.1.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/sebastianbergmann/comparator.git", "url": "https://github.com/sebastianbergmann/comparator.git",
"reference": "131942b86d3587291067a94f295498ab6ac79c20" "reference": "fa37b9e2ca618cb051d71b60120952ee8ca8b03d"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/131942b86d3587291067a94f295498ab6ac79c20", "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/fa37b9e2ca618cb051d71b60120952ee8ca8b03d",
"reference": "131942b86d3587291067a94f295498ab6ac79c20", "reference": "fa37b9e2ca618cb051d71b60120952ee8ca8b03d",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -933,12 +933,12 @@
"sebastian/exporter": "^6.0" "sebastian/exporter": "^6.0"
}, },
"require-dev": { "require-dev": {
"phpunit/phpunit": "^11.0" "phpunit/phpunit": "^11.3"
}, },
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-main": "6.0-dev" "dev-main": "6.1-dev"
} }
}, },
"autoload": { "autoload": {
@@ -978,7 +978,7 @@
"support": { "support": {
"issues": "https://github.com/sebastianbergmann/comparator/issues", "issues": "https://github.com/sebastianbergmann/comparator/issues",
"security": "https://github.com/sebastianbergmann/comparator/security/policy", "security": "https://github.com/sebastianbergmann/comparator/security/policy",
"source": "https://github.com/sebastianbergmann/comparator/tree/6.0.1" "source": "https://github.com/sebastianbergmann/comparator/tree/6.1.0"
}, },
"funding": [ "funding": [
{ {
@@ -986,7 +986,7 @@
"type": "github" "type": "github"
} }
], ],
"time": "2024-07-03T04:48:07+00:00" "time": "2024-09-11T15:42:56+00:00"
}, },
{ {
"name": "sebastian/complexity", "name": "sebastian/complexity",
@@ -1555,28 +1555,28 @@
}, },
{ {
"name": "sebastian/type", "name": "sebastian/type",
"version": "5.0.1", "version": "5.1.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/sebastianbergmann/type.git", "url": "https://github.com/sebastianbergmann/type.git",
"reference": "fb6a6566f9589e86661291d13eba708cce5eb4aa" "reference": "461b9c5da241511a2a0e8f240814fb23ce5c0aac"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/type/zipball/fb6a6566f9589e86661291d13eba708cce5eb4aa", "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/461b9c5da241511a2a0e8f240814fb23ce5c0aac",
"reference": "fb6a6566f9589e86661291d13eba708cce5eb4aa", "reference": "461b9c5da241511a2a0e8f240814fb23ce5c0aac",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"php": ">=8.2" "php": ">=8.2"
}, },
"require-dev": { "require-dev": {
"phpunit/phpunit": "^11.0" "phpunit/phpunit": "^11.3"
}, },
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-main": "5.0-dev" "dev-main": "5.1-dev"
} }
}, },
"autoload": { "autoload": {
@@ -1600,7 +1600,7 @@
"support": { "support": {
"issues": "https://github.com/sebastianbergmann/type/issues", "issues": "https://github.com/sebastianbergmann/type/issues",
"security": "https://github.com/sebastianbergmann/type/security/policy", "security": "https://github.com/sebastianbergmann/type/security/policy",
"source": "https://github.com/sebastianbergmann/type/tree/5.0.1" "source": "https://github.com/sebastianbergmann/type/tree/5.1.0"
}, },
"funding": [ "funding": [
{ {
@@ -1608,7 +1608,7 @@
"type": "github" "type": "github"
} }
], ],
"time": "2024-07-03T05:11:49+00:00" "time": "2024-09-17T13:12:04+00:00"
}, },
{ {
"name": "sebastian/version", "name": "sebastian/version",
@@ -1721,7 +1721,7 @@
"prefer-stable": false, "prefer-stable": false,
"prefer-lowest": false, "prefer-lowest": false,
"platform": { "platform": {
"php": "^8.2" "php": ">=8.4"
}, },
"platform-dev": [], "platform-dev": [],
"plugin-api-version": "2.6.0" "plugin-api-version": "2.6.0"

View File

@@ -25,50 +25,38 @@ use InvalidArgumentException;
* *
* @template T The type of value represented by this option * @template T The type of value represented by this option
*/ */
readonly class Option class Option
{ {
/** @var T|null $value The value for this option */ /** @var T|null $value The value for this option */
private mixed $value; private mixed $val;
/** /**
* @param T|null $value The possibly null value for this option * @param T|null $value The possibly null value for this option
*/ */
private function __construct(mixed $value = null) private function __construct(mixed $value = null)
{ {
$this->value = $value; $this->val = $value;
} }
/** /**
* Get the value of this option * @var T The value of this option (read-only)
* * @throws InvalidArgumentException If called on a `None` option
* @return T The value of the option
*/ */
public function get(): mixed public mixed $value {
{ get => match ($this->val) {
return match (true) { null => throw new InvalidArgumentException('Cannot get the value of a None option'),
$this->isSome() => $this->value, default => $this->val,
default => throw new InvalidArgumentException('Cannot get the value of a None option'),
}; };
} }
/** /** @var bool True if the option is `None`, false if it is `Some` */
* Does this option have a `None` value? public bool $isNone {
* get => is_null($this->val);
* @return bool True if the option is `None`, false if it is `Some`
*/
public function isNone(): bool
{
return is_null($this->value);
} }
/** /** @var bool True if the option is `Some`, false if it is `None` */
* Does this option have a `Some` value? public bool $isSome{
* get => !$this->isNone;
* @return bool True if the option is `Some`, false if it is `None`
*/
public function isSome(): bool
{
return !$this->isNone();
} }
/** /**
@@ -79,7 +67,7 @@ readonly class Option
*/ */
public function getOrDefault(mixed $default): mixed public function getOrDefault(mixed $default): mixed
{ {
return $this->value ?? $default; return $this->val ?? $default;
} }
/** /**
@@ -91,18 +79,19 @@ readonly class Option
*/ */
public function getOrCall(callable $f): mixed public function getOrCall(callable $f): mixed
{ {
return $this->value ?? $f(); return $this->val ?? $f();
} }
/** /**
* Get the value, or throw the * Get the value, or throw the exception using the given function
*
* @param callable(): Exception $exFunc A function to construct the exception to throw * @param callable(): Exception $exFunc A function to construct the exception to throw
* @return T The value of the option if `Some` * @return T The value of the option if `Some`
* @throws Exception If the option is `None` * @throws Exception If the option is `None`
*/ */
public function getOrThrow(callable $exFunc): mixed public function getOrThrow(callable $exFunc): mixed
{ {
return $this->value ?? throw $exFunc(); return $this->val ?? throw $exFunc();
} }
/** /**
@@ -117,7 +106,7 @@ readonly class Option
*/ */
public function bind(callable $f): Option public function bind(callable $f): Option
{ {
return $this->isNone() ? $this : $f($this->get()); return $this->isNone ? $this : $f($this->val);
} }
/** /**
@@ -130,8 +119,8 @@ readonly class Option
public function contains(mixed $value, bool $strict = true): bool public function contains(mixed $value, bool $strict = true): bool
{ {
return match (true) { return match (true) {
$this->isNone() => false, $this->isNone => false,
default => $strict ? $this->value === $value : $this->value == $value, default => $strict ? $this->val === $value : $this->val == $value,
}; };
} }
@@ -143,7 +132,7 @@ readonly class Option
*/ */
public function exists(callable $f): bool public function exists(callable $f): bool
{ {
return $this->isSome() ? $f($this->value) : false; return $this->isSome ? $f($this->val) : false;
} }
/** /**
@@ -155,7 +144,7 @@ readonly class Option
*/ */
public function map(callable $f): self public function map(callable $f): self
{ {
return $this->isSome() ? self::Some($f($this->get())) : $this; return $this->isSome ? self::Some($f($this->val)) : $this;
} }
/** /**
@@ -165,8 +154,8 @@ readonly class Option
*/ */
public function iter(callable $f): void public function iter(callable $f): void
{ {
if ($this->isSome()) { if ($this->isSome) {
$f($this->value); $f($this->val);
} }
} }
@@ -178,7 +167,7 @@ readonly class Option
*/ */
public function filter(callable $f): self public function filter(callable $f): self
{ {
return $this->isNone() || $this->exists($f) ? $this : self::None(); return $this->isNone || $this->exists($f) ? $this : self::None();
} }
/** /**
@@ -188,7 +177,7 @@ readonly class Option
*/ */
public function unwrap(): mixed public function unwrap(): mixed
{ {
return $this->value; return $this->val;
} }
/** /**
@@ -210,7 +199,7 @@ readonly class Option
*/ */
public function toArray(): array public function toArray(): array
{ {
return $this->isSome() ? [$this->value] : []; return $this->isSome ? [$this->val] : [];
} }
/** /**
@@ -221,8 +210,8 @@ readonly class Option
public function toPhpOption(): mixed public function toPhpOption(): mixed
{ {
return match (true) { return match (true) {
$this->isNone() && class_exists('PhpOption\None') => call_user_func('PhpOption\None::create'), $this->isNone && class_exists('PhpOption\None') => call_user_func('PhpOption\None::create'),
class_exists('PhpOption\Some') => call_user_func('PhpOption\Some::create', $this->value), class_exists('PhpOption\Some') => call_user_func('PhpOption\Some::create', $this->val),
default => throw new Error('PhpOption types could not be found'), default => throw new Error('PhpOption types could not be found'),
}; };
} }
@@ -261,7 +250,7 @@ readonly class Option
{ {
return match (true) { return match (true) {
is_object($value) && is_a($value, 'PhpOption\Option') => is_object($value) && is_a($value, 'PhpOption\Option') =>
$value->isDefined() ? self::Some($value->get()) : self::None(), $value->isDefined() ? self::Some($value->get()) : self::None(),
default => new self($value), default => new self($value),
}; };
} }

View File

@@ -25,7 +25,7 @@ use InvalidArgumentException;
* @template TOK The type of the OK result * @template TOK The type of the OK result
* @template TError The type of the error result * @template TError The type of the error result
*/ */
readonly class Result class Result
{ {
/** @var Option<TOK> The OK value for this result */ /** @var Option<TOK> The OK value for this result */
private Option $okValue; private Option $okValue;
@@ -45,46 +45,24 @@ readonly class Result
$this->errorValue = Option::of($errorValue); $this->errorValue = Option::of($errorValue);
} }
/** /** @var TOK The OK value (will throw if result is not OK) */
* Get the value for an `OK` result public mixed $ok {
* get => $this->okValue->value;
* @return TOK The OK value for this result
* @throws InvalidArgumentException If the result is an `Error` result
*/
public function getOK(): mixed
{
return $this->okValue->get();
} }
/** /** @var TError The error value (will throw if result is not Error) */
* Get the value for an `Error` result public mixed $error {
* get => $this->errorValue->value;
* @return TError The error value for this result
* @throws InvalidArgumentException If the result is an `OK` result
*/
public function getError(): mixed
{
return $this->errorValue->get();
} }
/** /** @var bool True if the result is `OK`, false if it is `Error` */
* Is this result `OK`? public bool $isOK {
* get => $this->okValue->isSome;
* @return bool True if the result is `OK`, false if it is `Error`
*/
public function isOK(): bool
{
return $this->okValue->isSome();
} }
/** /** @var bool True if the result is `Error`, false if it is `OK` */
* Is this result `Error`? public bool $isError {
* get => $this->errorValue->isSome;
* @return bool True if the result is `Error`, false if it is `OK`
*/
public function isError(): bool
{
return $this->errorValue->isSome();
} }
/** /**
@@ -100,7 +78,7 @@ readonly class Result
*/ */
public function bind(callable $f): Result public function bind(callable $f): Result
{ {
return $this->isError() ? $this : $f($this->getOK()); return $this->isError ? $this : $f($this->ok);
} }
/** /**
@@ -113,8 +91,8 @@ readonly class Result
public function contains(mixed $value, bool $strict = true): bool public function contains(mixed $value, bool $strict = true): bool
{ {
return match (true) { return match (true) {
$this->isError() => false, $this->isError => false,
default => $this->okValue->contains($value, $strict), default => $this->okValue->contains($value, $strict),
}; };
} }
@@ -126,7 +104,7 @@ readonly class Result
*/ */
public function exists(callable $f): bool public function exists(callable $f): bool
{ {
return $this->isOK() ? $f($this->okValue->get()) : false; return $this->isOK ? $f($this->ok) : false;
} }
/** /**
@@ -138,7 +116,7 @@ readonly class Result
*/ */
public function map(callable $f): self public function map(callable $f): self
{ {
return $this->isOK() ? self::OK($f($this->getOK())) : $this; return $this->isOK ? self::OK($f($this->ok)) : $this;
} }
/** /**
@@ -150,7 +128,7 @@ readonly class Result
*/ */
public function mapError(callable $f): self public function mapError(callable $f): self
{ {
return $this->isError() ? self::Error($f($this->getError())) : $this; return $this->isError ? self::Error($f($this->error)) : $this;
} }
/** /**
@@ -160,8 +138,8 @@ readonly class Result
*/ */
public function iter(callable $f): void public function iter(callable $f): void
{ {
if ($this->isOK()) { if ($this->isOK) {
$f($this->getOK()); $f($this->ok);
} }
} }
@@ -182,7 +160,7 @@ readonly class Result
*/ */
public function toOption(): Option public function toOption(): Option
{ {
return $this->isOK() ? Option::Some($this->getOK()) : Option::None(); return $this->isOK ? Option::Some($this->ok) : Option::None();
} }
/** /**

View File

@@ -20,43 +20,43 @@ use PHPUnit\Framework\TestCase;
*/ */
class OptionTest extends TestCase class OptionTest extends TestCase
{ {
#[TestDox('Get succeeds for Some')] #[TestDox('Value succeeds for Some')]
public function testGetSucceedsForSome(): void public function testValueSucceedsForSome(): void
{ {
$it = Option::Some(9); $it = Option::Some(9);
$this->assertTrue($it->isSome(), 'The option should have been "Some"'); $this->assertTrue($it->isSome, 'The option should have been "Some"');
$this->assertEquals(9, $it->get(), 'The value was incorrect'); $this->assertEquals(9, $it->value, 'The value was incorrect');
} }
#[TestDox('Get fails for None')] #[TestDox('Value fails for None')]
public function testGetFailsForNone(): void public function testValueFailsForNone(): void
{ {
$this->expectException(InvalidArgumentException::class); $this->expectException(InvalidArgumentException::class);
Option::None()->get(); Option::None()->value;
} }
#[TestDox('IsNone succeeds with None')] #[TestDox('IsNone succeeds with None')]
public function testIsNoneSucceedsWithNone(): void public function testIsNoneSucceedsWithNone(): void
{ {
$this->assertTrue(Option::None()->isNone(), '"None" should return true'); $this->assertTrue(Option::None()->isNone, '"None" should return true');
} }
#[TestDox('IsNone succeeds with Some')] #[TestDox('IsNone succeeds with Some')]
public function testIsNoneSucceedsWithSome(): void public function testIsNoneSucceedsWithSome(): void
{ {
$this->assertFalse(Option::Some(8)->isNone(), '"Some" should return false'); $this->assertFalse(Option::Some(8)->isNone, '"Some" should return false');
} }
#[TestDox('IsSome succeeds with None')] #[TestDox('IsSome succeeds with None')]
public function testIsSomeSucceedsWithNone(): void public function testIsSomeSucceedsWithNone(): void
{ {
$this->assertFalse(Option::None()->isSome(), '"None" should return false'); $this->assertFalse(Option::None()->isSome, '"None" should return false');
} }
#[TestDox('IsSome succeeds with Some')] #[TestDox('IsSome succeeds with Some')]
public function testIsSomeSucceedsWithSome(): void public function testIsSomeSucceedsWithSome(): void
{ {
$this->assertTrue(Option::Some('boo')->isSome(), '"Some" should return true'); $this->assertTrue(Option::Some('boo')->isSome, '"Some" should return true');
} }
#[TestDox('GetOrDefault succeeds with None')] #[TestDox('GetOrDefault succeeds with None')]
@@ -105,7 +105,7 @@ class OptionTest extends TestCase
{ {
$original = Option::None(); $original = Option::None();
$bound = $original->bind(fn($it) => Option::Some('value')); $bound = $original->bind(fn($it) => Option::Some('value'));
$this->assertTrue($bound->isNone(), 'The option should have been None'); $this->assertTrue($bound->isNone, 'The option should have been None');
$this->assertSame($original, $bound, 'The same None instance should have been returned'); $this->assertSame($original, $bound, 'The same None instance should have been returned');
} }
@@ -113,15 +113,15 @@ class OptionTest extends TestCase
public function testBindSucceedsWithSomeAndSome(): void public function testBindSucceedsWithSomeAndSome(): void
{ {
$bound = Option::Some('hello')->bind(fn($it) => Option::Some('goodbye')); $bound = Option::Some('hello')->bind(fn($it) => Option::Some('goodbye'));
$this->assertTrue($bound->isSome(), 'The option should have been Some'); $this->assertTrue($bound->isSome, 'The option should have been Some');
$this->assertEquals('goodbye', $bound->get(), 'The bound function was not called'); $this->assertEquals('goodbye', $bound->value, 'The bound function was not called');
} }
#[TestDox('Bind succeeds with Some and None')] #[TestDox('Bind succeeds with Some and None')]
public function testBindSucceedsWithSomeAndNone(): void public function testBindSucceedsWithSomeAndNone(): void
{ {
$bound = Option::Some('greetings')->bind(fn($it) => Option::None()); $bound = Option::Some('greetings')->bind(fn($it) => Option::None());
$this->assertTrue($bound->isNone(), 'The option should have been None'); $this->assertTrue($bound->isNone, 'The option should have been None');
} }
#[TestDox('Contains succeeds with None')] #[TestDox('Contains succeeds with None')]
@@ -182,7 +182,7 @@ class OptionTest extends TestCase
$tattle->called = true; $tattle->called = true;
return 'hello'; return 'hello';
}); });
$this->assertTrue($mapped->isNone(), 'The mapped option should be "None"'); $this->assertTrue($mapped->isNone, 'The mapped option should be "None"');
$this->assertFalse($tattle->called, 'The mapping function should not have been called'); $this->assertFalse($tattle->called, 'The mapping function should not have been called');
$this->assertSame($none, $mapped, 'The same "None" instance should have been returned'); $this->assertSame($none, $mapped, 'The same "None" instance should have been returned');
} }
@@ -191,8 +191,8 @@ class OptionTest extends TestCase
public function testMapSucceedsWithSome(): void public function testMapSucceedsWithSome(): void
{ {
$mapped = Option::Some('abc ')->map(fn($it) => str_repeat($it, 2)); $mapped = Option::Some('abc ')->map(fn($it) => str_repeat($it, 2));
$this->assertTrue($mapped->isSome(), 'The mapped option should be "Some"'); $this->assertTrue($mapped->isSome, 'The mapped option should be "Some"');
$this->assertEquals('abc abc ', $mapped->get(), 'The mapping function was not called correctly'); $this->assertEquals('abc abc ', $mapped->value, 'The mapping function was not called correctly');
} }
#[TestDox('Map fails with Some when mapping is null')] #[TestDox('Map fails with Some when mapping is null')]
@@ -228,7 +228,7 @@ class OptionTest extends TestCase
$tattle->called = true; $tattle->called = true;
return true; return true;
}); });
$this->assertTrue($filtered->isNone(), 'The filtered option should have been "None"'); $this->assertTrue($filtered->isNone, 'The filtered option should have been "None"');
$this->assertFalse($tattle->called, 'The callable should not have been called'); $this->assertFalse($tattle->called, 'The callable should not have been called');
$this->assertSame($none, $filtered, 'The "None" instance returned should have been the one passed'); $this->assertSame($none, $filtered, 'The "None" instance returned should have been the one passed');
} }
@@ -238,8 +238,8 @@ class OptionTest extends TestCase
{ {
$some = Option::Some(12); $some = Option::Some(12);
$filtered = $some->filter(fn($it) => $it % 2 === 0); $filtered = $some->filter(fn($it) => $it % 2 === 0);
$this->assertTrue($filtered->isSome(), 'The filtered option should have been "Some"'); $this->assertTrue($filtered->isSome, 'The filtered option should have been "Some"');
$this->assertEquals(12, $filtered->get(), 'The filtered option value is incorrect'); $this->assertEquals(12, $filtered->value, 'The filtered option value is incorrect');
$this->assertSame($some, $filtered, 'The same "Some" instance should have been returned'); $this->assertSame($some, $filtered, 'The same "Some" instance should have been returned');
} }
@@ -248,7 +248,7 @@ class OptionTest extends TestCase
{ {
$some = Option::Some(23); $some = Option::Some(23);
$filtered = $some->filter(fn($it) => $it % 2 === 0); $filtered = $some->filter(fn($it) => $it % 2 === 0);
$this->assertTrue($filtered->isNone(), 'The filtered option should have been "None"'); $this->assertTrue($filtered->isNone, 'The filtered option should have been "None"');
} }
#[TestDox('Unwrap succeeds with None')] #[TestDox('Unwrap succeeds with None')]
@@ -269,7 +269,7 @@ class OptionTest extends TestCase
$value = ''; $value = '';
$original = Option::Some('testing'); $original = Option::Some('testing');
$tapped = $original->tap( $tapped = $original->tap(
function (Option $it) use (&$value) { $value = $it->isSome() ? $it->get() : 'none'; }); function (Option $it) use (&$value) { $value = $it->isSome ? $it->value : 'none'; });
$this->assertEquals('testing', $value, 'The tapped function was not called'); $this->assertEquals('testing', $value, 'The tapped function was not called');
$this->assertSame($original, $tapped, 'The same option should have been returned'); $this->assertSame($original, $tapped, 'The same option should have been returned');
} }
@@ -280,7 +280,7 @@ class OptionTest extends TestCase
$value = ''; $value = '';
$original = Option::None(); $original = Option::None();
$tapped = $original->tap( $tapped = $original->tap(
function (Option $it) use (&$value) { $value = $it->isSome() ? $it->get() : 'none'; }); function (Option $it) use (&$value) { $value = $it->isSome ? $it->value : 'none'; });
$this->assertEquals('none', $value, 'The tapped function was not called'); $this->assertEquals('none', $value, 'The tapped function was not called');
$this->assertSame($original, $tapped, 'The same option should have been returned'); $this->assertSame($original, $tapped, 'The same option should have been returned');
} }
@@ -323,7 +323,7 @@ class OptionTest extends TestCase
public function testSomeSucceedsWithValue(): void public function testSomeSucceedsWithValue(): void
{ {
$it = Option::Some('hello'); $it = Option::Some('hello');
$this->assertTrue($it->isSome(), 'The option should have been "Some"'); $this->assertTrue($it->isSome, 'The option should have been "Some"');
} }
public function testSomeFailsWithNull(): void public function testSomeFailsWithNull(): void
@@ -335,34 +335,34 @@ class OptionTest extends TestCase
public function testNoneSucceeds(): void public function testNoneSucceeds(): void
{ {
$it = Option::None(); $it = Option::None();
$this->assertTrue($it->isNone(), 'The option should have been "None"'); $this->assertTrue($it->isNone, 'The option should have been "None"');
} }
public function testOfSucceedsWithNull(): void public function testOfSucceedsWithNull(): void
{ {
$it = Option::of(null); $it = Option::of(null);
$this->assertTrue($it->isNone(), '"null" should have created a "None" option'); $this->assertTrue($it->isNone, '"null" should have created a "None" option');
} }
public function testOfSucceedsWithNonNull(): void public function testOfSucceedsWithNonNull(): void
{ {
$it = Option::of('test'); $it = Option::of('test');
$this->assertTrue($it->isSome(), 'A non-null value should have created a "Some" option'); $this->assertTrue($it->isSome, 'A non-null value should have created a "Some" option');
$this->assertEquals('test', $it->get(), 'The value was not assigned correctly'); $this->assertEquals('test', $it->value, 'The value was not assigned correctly');
} }
#[TestDox('Of succeeds with PhpOption\Some')] #[TestDox('Of succeeds with PhpOption\Some')]
public function testOfSucceedsWithPhpOptionSome(): void public function testOfSucceedsWithPhpOptionSome(): void
{ {
$it = Option::of(Some::create('something')); $it = Option::of(Some::create('something'));
$this->assertTrue($it->isSome(), 'A "Some" PhpOption should have created a "Some" option'); $this->assertTrue($it->isSome, 'A "Some" PhpOption should have created a "Some" option');
$this->assertEquals('something', $it->get(), 'The value was not assigned correctly'); $this->assertEquals('something', $it->value, 'The value was not assigned correctly');
} }
#[TestDox('Of succeeds with PhpOption\None')] #[TestDox('Of succeeds with PhpOption\None')]
public function testOfSucceedsWithPhpOptionNone(): void public function testOfSucceedsWithPhpOptionNone(): void
{ {
$it = Option::of(None::create()); $it = Option::of(None::create());
$this->assertTrue($it->isNone(), 'A "None" PhpOption should have created a "None" option'); $this->assertTrue($it->isNone, 'A "None" PhpOption should have created a "None" option');
} }
} }

View File

@@ -18,76 +18,76 @@ use PHPUnit\Framework\TestCase;
*/ */
class ResultTest extends TestCase class ResultTest extends TestCase
{ {
#[TestDox('GetOK succeeds for OK result')] #[TestDox('OK property succeeds for OK result')]
public function testGetOKSucceedsForOKResult(): void public function testOKPropertySucceedsForOKResult(): void
{ {
$result = Result::OK('yay'); $result = Result::OK('yay');
$this->assertEquals('yay', $result->getOK(), 'The OK result should have been returned'); $this->assertEquals('yay', $result->ok, 'The OK result should have been returned');
} }
#[TestDox('GetOK fails for Error result')] #[TestDox('OK property fails for Error result')]
public function testGetOKFailsForErrorResult(): void public function testOKPropertyFailsForErrorResult(): void
{ {
$this->expectException(InvalidArgumentException::class); $this->expectException(InvalidArgumentException::class);
Result::Error('whoops')->getOK(); Result::Error('whoops')->ok;
} }
#[TestDox('GetError succeeds for Error result')] #[TestDox('Error property succeeds for Error result')]
public function testGetErrorSucceedsForErrorResult(): void public function testErrorPropertySucceedsForErrorResult(): void
{ {
$result = Result::Error('boo'); $result = Result::Error('boo');
$this->assertEquals('boo', $result->getError(), 'The Error result should have been returned'); $this->assertEquals('boo', $result->error, 'The Error result should have been returned');
} }
#[TestDox('GetError fails for OK result')] #[TestDox('Error property fails for OK result')]
public function testGetErrorFailsForOKResult(): void public function testErrorPropertyFailsForOKResult(): void
{ {
$this->expectException(InvalidArgumentException::class); $this->expectException(InvalidArgumentException::class);
Result::OK('yeah')->getError(); Result::OK('yeah')->error;
} }
#[TestDox('IsOK succeeds for OK result')] #[TestDox('IsOK succeeds for OK result')]
public function testIsOKSucceedsForOKResult(): void public function testIsOKSucceedsForOKResult(): void
{ {
$result = Result::OK('ok'); $result = Result::OK('ok');
$this->assertTrue($result->isOK(), 'The check for "OK" should have returned true'); $this->assertTrue($result->isOK, 'The check for "OK" should have returned true');
} }
#[TestDox('IsOK succeeds for Error result')] #[TestDox('IsOK succeeds for Error result')]
public function testIsOKSucceedsForErrorResult(): void public function testIsOKSucceedsForErrorResult(): void
{ {
$result = Result::Error('error'); $result = Result::Error('error');
$this->assertFalse($result->isOK(), 'The check for "OK" should have returned false'); $this->assertFalse($result->isOK, 'The check for "OK" should have returned false');
} }
#[TestDox('IsError succeeds for Error result')] #[TestDox('IsError succeeds for Error result')]
public function testIsErrorSucceedsForErrorResult(): void public function testIsErrorSucceedsForErrorResult(): void
{ {
$result = Result::Error('not ok'); $result = Result::Error('not ok');
$this->assertTrue($result->isError(), 'The check for "Error" should have returned true'); $this->assertTrue($result->isError, 'The check for "Error" should have returned true');
} }
#[TestDox('IsError succeeds for OK result')] #[TestDox('IsError succeeds for OK result')]
public function testIsErrorSucceedsForOKResult(): void public function testIsErrorSucceedsForOKResult(): void
{ {
$result = Result::OK('fine'); $result = Result::OK('fine');
$this->assertFalse($result->isError(), 'The check for "Error" should have returned false'); $this->assertFalse($result->isError, 'The check for "Error" should have returned false');
} }
#[TestDox('Bind succeeds for OK with OK')] #[TestDox('Bind succeeds for OK with OK')]
public function testBindSucceedsForOKWithOK(): void public function testBindSucceedsForOKWithOK(): void
{ {
$result = Result::OK('one')->bind(fn($it) => Result::OK("$it two")); $result = Result::OK('one')->bind(fn($it) => Result::OK("$it two"));
$this->assertTrue($result->isOK(), 'The result should have been OK'); $this->assertTrue($result->isOK, 'The result should have been OK');
$this->assertEquals('one two', $result->getOK(), 'The bound function was not called'); $this->assertEquals('one two', $result->ok, 'The bound function was not called');
} }
#[TestDox('Bind succeeds for OK with Error')] #[TestDox('Bind succeeds for OK with Error')]
public function testBindSucceedsForOKWithError(): void public function testBindSucceedsForOKWithError(): void
{ {
$result = Result::OK('three')->bind(fn($it) => Result::Error('back to two')); $result = Result::OK('three')->bind(fn($it) => Result::Error('back to two'));
$this->assertTrue($result->isError(), 'The result should have been Error'); $this->assertTrue($result->isError, 'The result should have been Error');
$this->assertEquals('back to two', $result->getError(), 'The bound function was not called'); $this->assertEquals('back to two', $result->error, 'The bound function was not called');
} }
#[TestDox('Bind succeeds for Error')] #[TestDox('Bind succeeds for Error')]
@@ -95,7 +95,7 @@ class ResultTest extends TestCase
{ {
$original = Result::Error('oops'); $original = Result::Error('oops');
$result = $original->bind(fn($it) => Result::OK('never mind - it worked!')); $result = $original->bind(fn($it) => Result::OK('never mind - it worked!'));
$this->assertTrue($result->isError(), 'The result should have been Error'); $this->assertTrue($result->isError, 'The result should have been Error');
$this->assertSame($original, $result, 'The same Error result should have been returned'); $this->assertSame($original, $result, 'The same Error result should have been returned');
} }
@@ -153,8 +153,8 @@ class ResultTest extends TestCase
{ {
$ok = Result::OK('yard'); $ok = Result::OK('yard');
$mapped = $ok->map(fn($it) => strrev($it)); $mapped = $ok->map(fn($it) => strrev($it));
$this->assertTrue($mapped->isOK(), 'The mapped result should be "OK"'); $this->assertTrue($mapped->isOK, 'The mapped result should be "OK"');
$this->assertEquals('dray', $mapped->getOK(), 'The mapping function was not called correctly'); $this->assertEquals('dray', $mapped->ok, 'The mapping function was not called correctly');
} }
#[TestDox('Map fails for OK result when mapping is null')] #[TestDox('Map fails for OK result when mapping is null')]
@@ -174,7 +174,7 @@ class ResultTest extends TestCase
$tattle->called = true; $tattle->called = true;
return 'hello'; return 'hello';
}); });
$this->assertTrue($mapped->isError(), 'The mapped result should be "Error"'); $this->assertTrue($mapped->isError, 'The mapped result should be "Error"');
$this->assertFalse($tattle->called, 'The mapping function should not have been called'); $this->assertFalse($tattle->called, 'The mapping function should not have been called');
$this->assertSame($error, $mapped, 'The same "Error" instance should have been returned'); $this->assertSame($error, $mapped, 'The same "Error" instance should have been returned');
} }
@@ -189,7 +189,7 @@ class ResultTest extends TestCase
$tattle->called = true; $tattle->called = true;
return 'hello'; return 'hello';
}); });
$this->assertTrue($mapped->isOK(), 'The mapped result should be "OK"'); $this->assertTrue($mapped->isOK, 'The mapped result should be "OK"');
$this->assertFalse($tattle->called, 'The mapping function should not have been called'); $this->assertFalse($tattle->called, 'The mapping function should not have been called');
$this->assertSame($ok, $mapped, 'The same "OK" instance should have been returned'); $this->assertSame($ok, $mapped, 'The same "OK" instance should have been returned');
} }
@@ -199,8 +199,8 @@ class ResultTest extends TestCase
{ {
$error = Result::Error('taco'); $error = Result::Error('taco');
$mapped = $error->mapError(fn($it) => str_repeat('*', strlen($it))); $mapped = $error->mapError(fn($it) => str_repeat('*', strlen($it)));
$this->assertTrue($mapped->isError(), 'The mapped result should be "Error"'); $this->assertTrue($mapped->isError, 'The mapped result should be "Error"');
$this->assertEquals('****', $mapped->getError(), 'The mapping function was not called correctly'); $this->assertEquals('****', $mapped->error, 'The mapping function was not called correctly');
} }
#[TestDox('MapError fails for Error result when mapping is null')] #[TestDox('MapError fails for Error result when mapping is null')]
@@ -246,15 +246,15 @@ class ResultTest extends TestCase
public function testToOptionSucceedsForOKResult() public function testToOptionSucceedsForOKResult()
{ {
$value = Result::OK(99)->toOption(); $value = Result::OK(99)->toOption();
$this->assertTrue($value->isSome(), 'An "OK" result should map to a "Some" option'); $this->assertTrue($value->isSome, 'An "OK" result should map to a "Some" option');
$this->assertEquals(99, $value->get(), 'The value is not correct'); $this->assertEquals(99, $value->value, 'The value is not correct');
} }
#[TestDox('ToOption succeeds for Error result')] #[TestDox('ToOption succeeds for Error result')]
public function testToOptionSucceedsForErrorResult() public function testToOptionSucceedsForErrorResult()
{ {
$value = Result::Error('file not found')->toOption(); $value = Result::Error('file not found')->toOption();
$this->assertTrue($value->isNone(), 'An "Error" result should map to a "None" option'); $this->assertTrue($value->isNone, 'An "Error" result should map to a "None" option');
} }
#[TestDox('Tap succeeds for OK result')] #[TestDox('Tap succeeds for OK result')]
@@ -263,7 +263,7 @@ class ResultTest extends TestCase
$value = ''; $value = '';
$original = Result::OK('working'); $original = Result::OK('working');
$tapped = $original->tap(function (Result $it) use (&$value) { $tapped = $original->tap(function (Result $it) use (&$value) {
$value = $it->isOK() ? 'OK: ' . $it->getOK() : 'Error: ' . $it->getError(); $value = $it->isOK ? 'OK: ' . $it->ok : 'Error: ' . $it->error;
}); });
$this->assertEquals('OK: working', $value, 'The tapped function was not called'); $this->assertEquals('OK: working', $value, 'The tapped function was not called');
$this->assertSame($original, $tapped, 'The same result should have been returned'); $this->assertSame($original, $tapped, 'The same result should have been returned');
@@ -275,7 +275,7 @@ class ResultTest extends TestCase
$value = ''; $value = '';
$original = Result::Error('failed'); $original = Result::Error('failed');
$tapped = $original->tap(function (Result $it) use (&$value) { $tapped = $original->tap(function (Result $it) use (&$value) {
$value = $it->isOK() ? 'OK: ' . $it->getOK() : 'Error: ' . $it->getError(); $value = $it->isOK ? 'OK: ' . $it->ok : 'Error: ' . $it->error;
}); });
$this->assertEquals('Error: failed', $value, 'The tapped function was not called'); $this->assertEquals('Error: failed', $value, 'The tapped function was not called');
$this->assertSame($original, $tapped, 'The same result should have been returned'); $this->assertSame($original, $tapped, 'The same result should have been returned');
@@ -285,8 +285,8 @@ class ResultTest extends TestCase
public function testOKSucceedsForNonNullResult(): void public function testOKSucceedsForNonNullResult(): void
{ {
$result = Result::OK('something'); $result = Result::OK('something');
$this->assertTrue($result->isOK(), 'The result should have been "OK"'); $this->assertTrue($result->isOK, 'The result should have been "OK"');
$this->assertEquals('something', $result->getOK(), 'The "OK" value was incorrect'); $this->assertEquals('something', $result->ok, 'The "OK" value was incorrect');
} }
#[TestDox('OK fails for null result')] #[TestDox('OK fails for null result')]
@@ -300,8 +300,8 @@ class ResultTest extends TestCase
public function testErrorSucceedsForNonNullResult(): void public function testErrorSucceedsForNonNullResult(): void
{ {
$result = Result::Error('sad trombone'); $result = Result::Error('sad trombone');
$this->assertTrue($result->isError(), 'The result should have been "Error"'); $this->assertTrue($result->isError, 'The result should have been "Error"');
$this->assertEquals('sad trombone', $result->getError(), 'The "Error" value was incorrect'); $this->assertEquals('sad trombone', $result->error, 'The "Error" value was incorrect');
} }
#[TestDox('Error fails for null result')] #[TestDox('Error fails for null result')]