Rust-style Option and Result Classes for PHP

feat(src/Option.php): add Option::takeIf with tests and docs to complete Option implementation

Ciaran 332ccdbf 8dc76479

+61 -10
+2 -2
README.md
··· 61 61 62 62 - Add useful methods 63 63 - Option 64 - - [ ] `take()` 65 - - [ ] `takeIf()` 64 + - [x] `takeIf()` 66 65 - [x] `None()` 67 66 - [x] `Some()` 68 67 - [x] `and()` ··· 76 75 - [x] `mapOr()` 77 76 - [x] `reduce()` 78 77 - [x] `replace()` 78 + - [x] `take()` 79 79 - [x] `unwrap()` 80 80 - [x] `unwrapOr()` 81 81 - Result
+23 -1
docs/classes/Ciarancoza/OptionResult/Option.md
··· 262 262 ### replace 263 263 264 264 ```php 265 - public replace(mixed $value): mixed 265 + public replace(mixed $value): self 266 266 ``` 267 267 268 268 **Parameters:** ··· 272 272 | `$value` | **mixed** | | 273 273 274 274 *** 275 + 276 + ### take 277 + 278 + ```php 279 + public take(): self 280 + ``` 281 + 282 + *** 283 + 284 + ### takeIf 285 + 286 + ```php 287 + public takeIf(callable $predicate): \Ciarancoza\OptionResult\Option 288 + ``` 289 + 290 + **Parameters:** 291 + 292 + | Parameter | Type | Description | 293 + |--------------|--------------|-------------| 294 + | `$predicate` | **callable** | | 295 + 296 + ***
+36 -3
src/Option.php
··· 224 224 * Replaces the actual value in the option by the value given in the parameter, returning the old value if present 225 225 * 226 226 * @template NT 227 + * 227 228 * @return Option<T> 228 229 */ 229 - public function replace(mixed $value) 230 + public function replace(mixed $value): self 230 231 { 231 232 $old = clone $this; 233 + if ($this->isNone() && $value !== null) { 234 + $this->isSome = true; 235 + } 232 236 $this->value = $value; 237 + 238 + return $old; 239 + } 240 + 241 + /* 242 + * Takes the value out of the option, leaving a `None` in its place 243 + * 244 + * return Option<T> 245 + */ 246 + public function take(): self 247 + { 248 + $old = clone $this; 249 + $this->value = null; 250 + $this->isSome = false; 251 + 252 + return $old; 253 + } 254 + 255 + /* 256 + * Takes the value out of the option, but only if the predicate evaluates to `true`. 257 + * 258 + * @param callable(T): bool $predicate 259 + * @return Option<T> 260 + */ 261 + public function takeIf(callable $predicate): Option 262 + { 233 263 if ($this->isNone()) { 234 - $this->isSome = true; 264 + return self::None(); 265 + } 266 + if ($predicate($this->value)) { 267 + return $this->take(); 235 268 } 236 269 237 - return $old; 270 + return self::None(); 238 271 } 239 272 }
-4
tests/OptionTest.php
··· 193 193 194 194 public function test_take(): void 195 195 { 196 - $this->markTestIncomplete('TODO'); 197 - 198 196 $x = Option::Some(2); 199 197 $y = $x->take(); 200 198 $this->assertTrue($x->isNone()); ··· 209 207 210 208 public function test_take_if(): void 211 209 { 212 - $this->markTestIncomplete('TODO'); 213 - 214 210 $x = Option::Some(42); 215 211 $prev = $x->takeIf(function (&$v) { 216 212 if ($v === 42) {