Type   A
last analyzed

Complexity

Total Complexity 9

Size/Duplication

Total Lines 73
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
dl 0
loc 73
rs 10
c 0
b 0
f 0
wmc 9

3 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
B applyConstructorArgumentsPatterns() 0 30 5
A match() 0 21 3
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Scalp\PatternMatching\Pattern;
6
7
use const Scalp\__;
0 ignored issues
show
Bug introduced by
The type Scalp\__ was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
8
use Scalp\PatternMatching\CaseClass;
9
use Scalp\PatternMatching\Exception\InvalidPatternsNumber;
10
use const Scalp\Utils\isInstanceOfType;
0 ignored issues
show
Bug introduced by
The type Scalp\Utils\isInstanceOfType was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
11
use const Scalp\Utils\Success;
12
use function Scalp\None;
13
use Scalp\Option;
14
use function Scalp\papply;
0 ignored issues
show
Bug introduced by
The type Scalp\papply was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
15
use function Scalp\Some;
16
use function Scalp\Utils\delay;
17
use const Scalp\Utils\Failure;
18
use Scalp\Utils\TryCatch;
19
use function Scalp\Utils\type;
0 ignored issues
show
Bug introduced by
The type Scalp\Utils\type was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
Bug introduced by
This use statement conflicts with another class in this namespace, Scalp\PatternMatching\Pattern\type. Consider defining an alias.

Let?s assume that you have a directory layout like this:

.
|-- OtherDir
|   |-- Bar.php
|   `-- Foo.php
`-- SomeDir
    `-- Foo.php

and let?s assume the following content of Bar.php:

// Bar.php
namespace OtherDir;

use SomeDir\Foo; // This now conflicts the class OtherDir\Foo

If both files OtherDir/Foo.php and SomeDir/Foo.php are loaded in the same runtime, you will see a PHP error such as the following:

PHP Fatal error:  Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php

However, as OtherDir/Foo.php does not necessarily have to be loaded and the error is only triggered if it is loaded before OtherDir/Bar.php, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias:

// Bar.php
namespace OtherDir;

use SomeDir\Foo as SomeDirFoo; // There is no conflict anymore.
Loading history...
20
21
final class Type extends Pattern implements Binding
22
{
23
    use Bind;
24
25
    private $type;
26
    private $patterns;
27
28
    public function __construct(string $type, Pattern ...$patterns)
29
    {
30
        $this->type = $type;
31
        $this->patterns = $patterns;
32
    }
33
34
    public function match($x): Option
35
    {
36
        $typeMatch = Some($x)
37
            ->filter(papply(isInstanceOfType, __, $this->type));
38
39
        if ($typeMatch->isEmpty() || empty($this->patterns)) {
40
            return $typeMatch->flatMap(function (): Option { return Some([]); });
41
        }
42
43
        /** @var TryCatch $caseClass */
44
        $caseClass = $typeMatch
45
                ->filter(papply(isInstanceOfType, __, CaseClass::class))
46
                ->fold(
47
                    delay(Failure, new \RuntimeException('Argument must be CaseClass')),
48
                    Success
49
                );
50
51
        return $caseClass
52
                ->map(function (CaseClass $cc): array { return $cc->deconstruct(); })
53
                ->map(papply(\Closure::fromCallable([$this, 'applyConstructorArgumentsPatterns']), type($x), __, $this->patterns))
54
                ->get();
55
    }
56
57
    /**
58
     * @param string    $type
59
     * @param array     $arguments
60
     * @param Pattern[] $patterns
61
     *
62
     * @return Option
63
     */
64
    private function applyConstructorArgumentsPatterns(string $type, array $arguments, array $patterns): Option
65
    {
66
        $argumentsNumber = \count($arguments);
67
        $patternsNumber = \count($patterns);
68
69
        if ($argumentsNumber !== $patternsNumber) {
70
            throw InvalidPatternsNumber::create($type, $argumentsNumber, $patternsNumber);
71
        }
72
73
        $currentPattern = 0;
74
75
        $values = [];
76
77
        foreach ($arguments as $argument) {
78
            $pattern = $patterns[$currentPattern];
79
80
            $res = $pattern->match($argument);
81
82
            if ($res->isEmpty()) {
83
                return None();
84
            }
85
86
            $value = $res->get();
87
88
            $values = array_merge($values, is_array($value) ? $value : [$value]);
89
90
            $currentPattern = $currentPattern + 1;
91
        }
92
93
        return Some($values);
94
    }
95
}
96