Line   A
last analyzed

Complexity

Total Complexity 15

Size/Duplication

Total Lines 61
Duplicated Lines 0 %

Test Coverage

Coverage 33.33%

Importance

Changes 0
Metric Value
eloc 21
dl 0
loc 61
ccs 9
cts 27
cp 0.3333
rs 10
c 0
b 0
f 0
wmc 15

7 Methods

Rating   Name   Duplication   Size   Complexity  
A withLetter() 0 3 1
A __construct() 0 3 1
A suitablePosition() 0 9 5
A jsonSerialize() 0 3 1
A fillRow() 0 9 2
A withWord() 0 12 4
A getIterator() 0 3 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace App\Crossword\Features\Constructor\Scanner\Grid;
6
7
use App\Crossword\Features\Constructor\Scanner\Exception\WordNotFitException;
8
use ArrayIterator;
9
use IteratorAggregate;
10
use JsonSerializable;
11
12
/**
13
 * @psalm-immutable
14
 */
15
final class Line implements IteratorAggregate, JsonSerializable
16
{
17
    private Row $row;
18
19
    public function __construct(Row $row)
20
    {
21
        $this->row = clone $row;
22
    }
23
24 1
    public static function withLetter(Row $row, string $letter): self
25
    {
26 1
        return new Line(Row::withCell($row, 0, Cell::withLetter($row->cell(0), $letter)));
27
    }
28
29 4
    public static function withWord(Row $row, string $word): self
30
    {
31 4
        for ($counter = 0; $counter < 3; $counter++) {
32 4
            if (self::suitablePosition($row, $word)) {
33 3
                return new Line(self::fillRow($row, $word));
34
            }
35
36 3
            $cell = $row->cell(0);
37 3
            $cell->isEmpty() && $row = $row->remove(0);
38
        }
39
40 1
        throw new WordNotFitException();
41
    }
42
43
    private static function suitablePosition(Row $row, string $word): bool
44
    {
45
        foreach ($row as $index => $cell) {
46
            if ($cell->isLetter() && strlen($word) >= $index + 1 && $word[(int) $index] === $cell->letter()) {
47
                return true;
48
            }
49
        }
50
51
        return false;
52
    }
53
54
    private static function fillRow(Row $row, string $word): Row
55
    {
56
        $withWord = [];
57
        $length = strlen($word);
58
        for ($counter = 0; $counter < $length; $counter++) {
59
            $withWord[] = Cell::withLetter($row->cell($counter), $word[$counter]);
60
        }
61
62
        return new Row(...$withWord);
63
    }
64
65
    public function getIterator(): ArrayIterator
66
    {
67
        return $this->row->getIterator();
68
    }
69
70
    /**
71
     * @psalm-suppress ImpureMethodCall
72
     */
73
    public function jsonSerialize(): array
74
    {
75
        return array_map(static fn (Cell $cell): array => $cell->jsonSerialize(), $this->getIterator()->getArrayCopy());
76
    }
77
}
78