Passed
Push — master ( 5707d5...8a512d )
by Magnar Ovedal
02:59
created

Coder::format()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 17
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 4

Importance

Changes 0
Metric Value
cc 4
eloc 8
nc 4
nop 1
dl 0
loc 17
ccs 9
cts 9
cp 1
crap 4
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Stadly\PasswordPolice\Formatter;
6
7
use Stadly\PasswordPolice\CharTree;
8
use Stadly\PasswordPolice\CodeMap;
9
use Stadly\PasswordPolice\Formatter;
10
11
final class Coder implements Formatter
12
{
13
    use Chaining;
14
15
    /**
16
     * @var CodeMap Code map for coding character trees.
17
     */
18
    private $codeMap;
19
20
    /**
21
     * @var CharTree[] Memoization of formatted character trees.
22
     */
23
    private $memoization = [];
24
25
    /**
26
     * @param CodeMap $codeMap Code map for coding character trees.
27
     */
28 5
    public function __construct(CodeMap $codeMap)
29
    {
30 5
        $this->codeMap = $codeMap;
31 5
    }
32
33
    /**
34
     * @param CharTree $charTree Character tree to format.
35
     * @return CharTree Coded variant of the character tree.
36
     */
37 5
    protected function applyCurrent(CharTree $charTree): CharTree
38
    {
39 5
        return $this->applyInternal($charTree);
40
    }
41
42
    /**
43
     * @param CharTree $charTree Character tree to format.
44
     * @return CharTree Coded variant of the character tree.
45
     */
46 5
    private function applyInternal(CharTree $charTree): CharTree
47
    {
48
        // When PHP 7.1 is no longer supported, change to using spl_object_id.
49 5
        $hash = spl_object_hash($charTree);
50
51 5
        if (!isset($this->memoization[$hash])) {
52 5
            $this->memoization[$hash] = $this->format($charTree);
53
        }
54
55 5
        return $this->memoization[$hash];
56
    }
57
58
    /**
59
     * @param CharTree $charTree Character tree to format.
60
     * @return CharTree Coded variant of the character tree. Memoization is not used.
61
     */
62 5
    private function format(CharTree $charTree): CharTree
63
    {
64 5
        if ($charTree->getRoot() === null) {
65 1
            return $charTree;
66
        }
67
68 4
        $branches = [];
69
70 4
        foreach ($this->codeMap->getMap($charTree) as $char => $codedChars) {
71 3
            $branch = $this->applyInternal($charTree->getBranchesAfterRoot((string)$char));
72
73 3
            foreach ($codedChars as $codedChar) {
74 3
                $branches[] = CharTree::fromString($codedChar, [$branch]);
75
            }
76
        }
77
78 4
        return CharTree::fromString('', $branches);
79
    }
80
}
81