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