···77/**
88 * Option<T> represents an optional value.
99 * An option may be `some` or `none`, where `some` contains a value and `none` does not.
1010+ *
1011 * @template T
1111-*/
1212-1313-class Option {
1414-1212+ */
1313+class Option
1414+{
1515 /**
1616- * Creates a `some` Option
1717- * @template T
1818- * @param T $value
1919- * @return Option<T>
2020- */
2121-2222- public static function Some(mixed $value = true): static {
1616+ * Creates a `some` Option
1717+ *
1818+ * @template T
1919+ *
2020+ * @param T $value
2121+ * @return Option<T>
2222+ */
2323+ public static function Some(mixed $value = true): static
2424+ {
2325 return new static($value, true);
2426 }
25272628 /**
2727- * Creates a `none` Option
2828- * @return Option<never>
2929- */
3030-3131- public static function None(): static {
2929+ * Creates a `none` Option
3030+ *
3131+ * @return Option<never>
3232+ */
3333+ public static function None(): static
3434+ {
3235 return new static(null, false);
3336 }
34373538 /** @param T $value */
3636-3739 private function __construct(
3838- private mixed $value,
4040+ private mixed $value,
3941 private bool $isSome
4042 ) {}
41434244 /** Returns `true` if the option is a `some` option. */
4343-4444- public function isSome(): bool {
4545+ public function isSome(): bool
4646+ {
4547 return $this->isSome;
4648 }
47494850 /** Returns `true` if the option is a `none` option. */
4949-5050- public function isNone(): bool {
5151- return !$this->isSome();
5151+ public function isNone(): bool
5252+ {
5353+ return ! $this->isSome();
5254 }
53555456 /**
5555- * Returns the contained value if `some`, otherwise throws UnwrapNoneException.
5656- * @throws UnwrapNoneException When called on `None`
5757- * @return T The contained value
5858- */
5757+ * Returns the contained value if `some`, otherwise throws UnwrapNoneException.
5858+ *
5959+ * @return T The contained value
6060+ *
6161+ * @throws UnwrapNoneException When called on `None`
6262+ */
6363+ public function unwrap(): mixed
6464+ {
6565+ if ($this->isNone()) {
6666+ throw new UnwrapNoneException;
6767+ }
59686060- public function unwrap(): mixed {
6161- if ($this->isNone()) throw new UnwrapNoneException;
6269 return $this->value;
6370 }
64716572 /**
6666- * Returns the contained `some` value or a provided default.
6767- * @param V $or
6868- * @return T|V
6969- */
7373+ * Returns the contained `some` value or a provided default.
7474+ *
7575+ * @param V $or
7676+ * @return T|V
7777+ */
7878+ public function unwrapOr(mixed $or): mixed
7979+ {
8080+ if ($this->isSome()) {
8181+ return $this->unwrap();
8282+ }
70837171- public function unwrapOr(mixed $or): mixed {
7272- if ($this->isSome()) return $this->unwrap();
7384 return $or;
7485 }
75867687 /**
7777- * Calls `fn` on contained value if `some`, returns `none` if `none`
7878- * @template U
7979- * @param callable(T): U $fn Function to transform the value
8080- * @return Option<U>
8181- */
8888+ * Calls `fn` on contained value if `some`, returns `none` if `none`
8989+ *
9090+ * @template U
9191+ *
9292+ * @param callable(T): U $fn Function to transform the value
9393+ * @return Option<U>
9494+ */
9595+ public function map(callable $fn): Option
9696+ {
9797+ if ($this->isNone()) {
9898+ return Option::None();
9999+ }
821008383- public function map(callable $fn): Option {
8484- if ($this->isNone()) return Option::None();
85101 return Option::Some($fn($this->value));
86102 }
8787-88103}
+103-72
src/Result.php
···66use Ciarancoza\OptionResult\Exceptions\UnwrapOkException;
7788/**
99- * Result<T, E> represents a success (`ok`) or an error (`err`)
1010- * @template T
1111- * @template E
1212-*/
1313-1414-class Result {
1515-1616- /**
1717- * Creates an `ok` result
1818- * @param T $value
1919- * @return Result<T,never>
2020- */
2121-2222- public static function Ok(mixed $value = true): static {
99+ * Result<T, E> represents a success (`ok`) or an error (`err`)
1010+ *
1111+ * @template T
1212+ * @template E
1313+ */
1414+class Result
1515+{
1616+ /**
1717+ * Creates an `ok` result
1818+ *
1919+ * @param T $value
2020+ * @return Result<T,never>
2121+ */
2222+ public static function Ok(mixed $value = true): static
2323+ {
2324 return new static($value, true);
2425 }
25262626- /**
2727- * Creates an `err` result
2828- * @param E $value
2929- * @return Result<never,E>
3030- */
3131-3232- public static function Err(mixed $value): static {
2727+ /**
2828+ * Creates an `err` result
2929+ *
3030+ * @param E $value
3131+ * @return Result<never,E>
3232+ */
3333+ public static function Err(mixed $value): static
3434+ {
3335 return new static($value, false);
3436 }
35373636- /** @param T $value */
3737-3838+ /** @param T $value */
3839 private function __construct(
3940 protected mixed $value,
4041 protected bool $isOk,
4142 ) {}
42434344 /** Returns `true` if the result is an `ok` result. */
4444-4545- public function isOk(): bool {
4545+ public function isOk(): bool
4646+ {
4647 return $this->isOk;
4748 }
48494950 /** Returns `true` if the result is an `err` result. */
5050-5151- public function isErr(): bool {
5252- return !$this->isOk();
5151+ public function isErr(): bool
5252+ {
5353+ return ! $this->isOk();
5354 }
54555556 /**
5656- * Returns `Some(T)` if `ok`, or `None` if `err`
5757- * @return Option<T>
5858- */
5757+ * Returns `Some(T)` if `ok`, or `None` if `err`
5858+ *
5959+ * @return Option<T>
6060+ */
6161+ public function getOk(): Option
6262+ {
6363+ if ($this->isErr()) {
6464+ return Option::None();
6565+ }
59666060- public function getOk(): Option {
6161- if ($this->isErr()) return Option::None();
6267 return Option::Some($this->value);
6368 }
64696570 /**
6666- * Returns `Some(E)` if `err`, or `None` if `ok`
6767- * @return Option<E>
6868- */
7171+ * Returns `Some(E)` if `err`, or `None` if `ok`
7272+ *
7373+ * @return Option<E>
7474+ */
7575+ public function getErr(): Option
7676+ {
7777+ if ($this->isOk()) {
7878+ return Option::None();
7979+ }
69807070- public function getErr(): Option {
7171- if ($this->isOk()) return Option::None();
7281 return Option::Some($this->value);
7382 }
74837584 /**
7676- * Returns the contained value if `ok`, otherwise throws UnwrapErrException
7777- * @throws UnwrapErrException
7878- * @return T The contained value
7979- */
8585+ * Returns the contained value if `ok`, otherwise throws UnwrapErrException
8686+ *
8787+ * @return T The contained value
8888+ *
8989+ * @throws UnwrapErrException
9090+ */
9191+ public function unwrap(): mixed
9292+ {
9393+ if ($this->isErr()) {
9494+ throw new UnwrapErrException;
9595+ }
80968181- public function unwrap(): mixed {
8282- if ($this->isErr()) throw new UnwrapErrException;
8397 return $this->value;
8498 }
859986100 /**
8787- * Returns the contained value if `err`, otherwise throws UnwrapOkException
8888- * @throws UnwrapOkException
8989- * @return E The contained error value
9090- */
101101+ * Returns the contained value if `err`, otherwise throws UnwrapOkException
102102+ *
103103+ * @return E The contained error value
104104+ *
105105+ * @throws UnwrapOkException
106106+ */
107107+ public function unwrapErr(): mixed
108108+ {
109109+ if ($this->isOk()) {
110110+ throw new UnwrapOkException;
111111+ }
911129292- public function unwrapErr(): mixed {
9393- if ($this->isOk()) throw new UnwrapOkException;
94113 return $this->value;
95114 }
9611597116 /**
9898- * Returns the contained `ok` value or a provided default.
9999- * @param V $or
100100- * @return T|V
101101- */
117117+ * Returns the contained `ok` value or a provided default.
118118+ *
119119+ * @param V $or
120120+ * @return T|V
121121+ */
122122+ public function unwrapOr(mixed $or): mixed
123123+ {
124124+ if ($this->isOk()) {
125125+ return $this->unwrap();
126126+ }
102127103103- public function unwrapOr(mixed $or): mixed {
104104- if ($this->isOk()) return $this->unwrap();
105128 return $or;
106129 }
107130108131 /**
109109- * If `ok`, transform the value with `$fn`
110110- * @template U
111111- * @param callable(T): U $fn Function to transform the value
112112- * @return Result<U,E>
113113- */
132132+ * If `ok`, transform the value with `$fn`
133133+ *
134134+ * @template U
135135+ *
136136+ * @param callable(T): U $fn Function to transform the value
137137+ * @return Result<U,E>
138138+ */
139139+ public function map(callable $fn): Result
140140+ {
141141+ if ($this->isErr()) {
142142+ return Result::Err($this->value);
143143+ }
114144115115- public function map(callable $fn): Result {
116116- if ($this->isErr()) return Result::Err($this->value);
117145 return Result::Ok($fn($this->value));
118146 }
119147120120-121148 /**
122122- * If `err`, transform the error value with `$fn`
123123- * @template U
124124- * @param callable(E): U $fn Function to transform the value
125125- * @return Result<T,U>
126126- */
149149+ * If `err`, transform the error value with `$fn`
150150+ *
151151+ * @template U
152152+ *
153153+ * @param callable(E): U $fn Function to transform the value
154154+ * @return Result<T,U>
155155+ */
156156+ public function mapErr(callable $fn): Result
157157+ {
158158+ if ($this->isOk()) {
159159+ return Result::Ok($this->value);
160160+ }
127161128128- public function mapErr(callable $fn): Result {
129129- if ($this->isOk()) return Result::Ok($this->value);
130162 return Result::Err($fn($this->value));
131163 }
132132-133164}