Passed
Pull Request — master (#12)
by Pol
12:15
created

Curry::getArguments()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 1
CRAP Score 1

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
c 2
b 0
f 0
nc 1
nop 2
dl 0
loc 3
ccs 1
cts 1
cp 1
crap 1
rs 10
1
<?php
2
3
/**
4
 * For the full copyright and license information, please view
5
 * the LICENSE file that was distributed with this source code.
6
 */
7
8
declare(strict_types=1);
9
10
namespace loophp\fpt;
11
12
use Closure;
13
use Generator;
14
use ReflectionFunction;
15
16
use function count;
17
18
/**
19
 * @psalm-immutable
20
 *
21
 * phpcs:disable Generic.Files.LineLength.TooLong
22
 */
23
final class Curry
24
{
25
    /**
26
     * @template T
27
     * @psalm-pure
28
     */
29 4
    public static function of(): Closure
30
    {
31
        return
32
            /**
33
             * @psalm-param positive-int|null $arity
34
             */
35 4
            static fn (callable $callable, ?int $arity = null): Closure =>
36
            /**
37
             * @psalm-param mixed ...$args
38
             *
39
             * @return mixed
40
             */
41 4
            static fn (...$args): mixed => self::curryN(
42 4
                ($arity ?? (new ReflectionFunction($callable))->getNumberOfRequiredParameters()) - count($args),
43
                $callable,
44 4
                ...self::getArguments([], $args)
45 4
            );
46
    }
47
48
    private static function curryN(int $numberOfArguments, callable $function, ...$args): mixed
49
    {
50
        return (0 >= $numberOfArguments)
51
            ? $function(...$args)
52
            :
53
            /**
54
             * @psalm-param mixed ...$argsNext
55
             *
56
             * @return mixed
57
             */
58
            static fn (...$argsNext): mixed => self::curryN($numberOfArguments - count($argsNext), $function, ...self::getArguments($args, $argsNext));
59
    }
60
61 4
    /**
62
     * @psalm-pure
63 4
     *
64 4
     * @psalm-param list<mixed> $args
65
     * @psalm-param list<mixed> $argsNext
66
     *
67
     * @psalm-return Generator<int, mixed>
68
     */
69
    private static function getArguments(array $args = [], array $argsNext = []): Generator
70
    {
71 4
        return yield from array_merge($args, $argsNext);
72
    }
73
}
74