parent
cb03f9452c
commit
952210f1ff
4 changed files with 226 additions and 0 deletions
@ -0,0 +1,57 @@ |
||||
--TEST-- |
||||
Symfony pattern: dynamic BackedEnum tryFrom with coalesce throw |
||||
--FILE-- |
||||
<?php |
||||
|
||||
enum Priority: int |
||||
{ |
||||
case Low = 1; |
||||
case High = 10; |
||||
} |
||||
|
||||
final class Argument |
||||
{ |
||||
public function __construct( |
||||
public string $name, |
||||
public string $typeName, |
||||
public array $suggestedValues, |
||||
) { |
||||
} |
||||
} |
||||
|
||||
function resolveEnum(Argument $argument, mixed $value): ?BackedEnum |
||||
{ |
||||
if (null === $value) { |
||||
return null; |
||||
} |
||||
|
||||
if ($value instanceof $argument->typeName) { |
||||
return $value; |
||||
} |
||||
|
||||
if (!is_string($value) && !is_int($value)) { |
||||
throw new InvalidArgumentException(get_debug_type($value)); |
||||
} |
||||
|
||||
return $argument->typeName::tryFrom($value) |
||||
?? throw new InvalidArgumentException(sprintf('Invalid "%s" value "%s".', $argument->name, $value)); |
||||
} |
||||
|
||||
function main(): void |
||||
{ |
||||
$argument = new Argument('priority', Priority::class, [1, 10]); |
||||
|
||||
var_dump(resolveEnum($argument, 10)); |
||||
var_dump(resolveEnum($argument, Priority::Low)); |
||||
|
||||
try { |
||||
resolveEnum($argument, 2); |
||||
} catch (InvalidArgumentException $e) { |
||||
echo $e->getMessage(), "\n"; |
||||
} |
||||
} |
||||
?> |
||||
--EXPECT-- |
||||
enum(Priority::High) |
||||
enum(Priority::Low) |
||||
Invalid "priority" value "2". |
||||
@ -0,0 +1,45 @@ |
||||
--TEST-- |
||||
Symfony pattern: lazy listener closure replaces itself with first-class callable |
||||
--FILE-- |
||||
<?php |
||||
|
||||
final class LazyListener |
||||
{ |
||||
public function __invoke(string $event): string |
||||
{ |
||||
echo "handle:$event\n"; |
||||
return strtoupper($event); |
||||
} |
||||
} |
||||
|
||||
function main(): void |
||||
{ |
||||
$listener = [static function (): LazyListener { |
||||
echo "factory\n"; |
||||
return new LazyListener(); |
||||
}]; |
||||
|
||||
$optimized = []; |
||||
$optimized[0] = null; |
||||
$closure = &$optimized[0]; |
||||
$closure = static function (...$args) use (&$listener, &$closure) { |
||||
if ($listener[0] instanceof Closure) { |
||||
$listener[0] = $listener[0](); |
||||
$listener[1] ??= '__invoke'; |
||||
} |
||||
|
||||
return ($closure = $listener(...))(...$args); |
||||
}; |
||||
|
||||
var_dump($optimized[0]('first')); |
||||
var_dump($optimized[0]('second')); |
||||
var_dump($listener[1]); |
||||
} |
||||
?> |
||||
--EXPECT-- |
||||
factory |
||||
handle:first |
||||
string(5) "FIRST" |
||||
handle:second |
||||
string(6) "SECOND" |
||||
string(8) "__invoke" |
||||
@ -0,0 +1,71 @@ |
||||
--TEST-- |
||||
Symfony pattern: nested array_merge unpack passed to method variadic |
||||
--FILE-- |
||||
<?php |
||||
|
||||
final class Envelope |
||||
{ |
||||
public function __construct(private array $groups) |
||||
{ |
||||
} |
||||
|
||||
public function all(): array |
||||
{ |
||||
return $this->groups; |
||||
} |
||||
|
||||
public function with(string ...$stamps): self |
||||
{ |
||||
$groups = $this->groups; |
||||
$groups['added'] = $stamps; |
||||
|
||||
return new self($groups); |
||||
} |
||||
|
||||
public function flat(): array |
||||
{ |
||||
return array_merge(...array_values($this->groups)); |
||||
} |
||||
} |
||||
|
||||
function mergeStamps(Envelope $decodedEnvelope, Envelope $failedEnvelope): Envelope |
||||
{ |
||||
return $decodedEnvelope->with(...array_merge(...array_values($failedEnvelope->all()))); |
||||
} |
||||
|
||||
function main(): void |
||||
{ |
||||
$failed = new Envelope([ |
||||
'first' => ['red', 'blue'], |
||||
'second' => ['green'], |
||||
]); |
||||
$decoded = new Envelope([ |
||||
'decoded' => ['base'], |
||||
]); |
||||
|
||||
var_dump(mergeStamps($decoded, $failed)->flat()); |
||||
var_dump(array_unique(array_merge(...array_values([ |
||||
'bus-a' => ['json', 'php'], |
||||
'bus-b' => ['json', 'xml'], |
||||
])))); |
||||
} |
||||
?> |
||||
--EXPECT-- |
||||
array(4) { |
||||
[0]=> |
||||
string(4) "base" |
||||
[1]=> |
||||
string(3) "red" |
||||
[2]=> |
||||
string(4) "blue" |
||||
[3]=> |
||||
string(5) "green" |
||||
} |
||||
array(3) { |
||||
[0]=> |
||||
string(4) "json" |
||||
[1]=> |
||||
string(3) "php" |
||||
[3]=> |
||||
string(3) "xml" |
||||
} |
||||
@ -0,0 +1,53 @@ |
||||
--TEST-- |
||||
Symfony pattern: array dim nullsafe call with boolean short-circuit |
||||
--FILE-- |
||||
<?php |
||||
|
||||
final class DeferredFuture |
||||
{ |
||||
public bool $completed = false; |
||||
|
||||
public function isComplete(): bool |
||||
{ |
||||
echo "isComplete\n"; |
||||
return $this->completed; |
||||
} |
||||
|
||||
public function complete(): void |
||||
{ |
||||
echo "complete\n"; |
||||
$this->completed = true; |
||||
} |
||||
} |
||||
|
||||
final class Multi |
||||
{ |
||||
public array $openHandles = []; |
||||
} |
||||
|
||||
function cancelHandle(Multi $multi, string $id): void |
||||
{ |
||||
$multi->openHandles[$id]?->isComplete() || $multi->openHandles[$id]?->complete(); |
||||
} |
||||
|
||||
function main(): void |
||||
{ |
||||
$multi = new Multi(); |
||||
$multi->openHandles['a'] = new DeferredFuture(); |
||||
|
||||
cancelHandle($multi, 'a'); |
||||
var_dump($multi->openHandles['a']->completed); |
||||
|
||||
cancelHandle($multi, 'a'); |
||||
|
||||
$multi->openHandles['b'] = null; |
||||
cancelHandle($multi, 'b'); |
||||
echo "done\n"; |
||||
} |
||||
?> |
||||
--EXPECT-- |
||||
isComplete |
||||
complete |
||||
bool(true) |
||||
isComplete |
||||
done |
||||
Loading…
Reference in new issue