Passed
Push — master ( de3d61...be839c )
by Alec
13:42 queued 13s
created

StyleToAnsiStringConverter::unset()   A

Complexity

Conditions 5
Paths 16

Size

Total Lines 17
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 11
c 0
b 0
f 0
nc 16
nop 3
dl 0
loc 17
rs 9.6111
1
<?php
2
3
declare(strict_types=1);
4
5
6
namespace AlecRabbit\Spinner\Extras;
7
8
use AlecRabbit\Spinner\Extras\Contract\IAnsiColorParser;
9
use AlecRabbit\Spinner\Extras\Contract\IStyleToAnsiStringConverter;
10
use AlecRabbit\Spinner\Extras\Contract\Style\IStyle;
11
use AlecRabbit\Spinner\Extras\Contract\Style\IStyleOptionsParser;
12
13
final class StyleToAnsiStringConverter implements IStyleToAnsiStringConverter
14
{
15
    private const SET = 'set';
16
    private const UNSET = 'unset';
17
18
    public function __construct(
19
        protected IAnsiColorParser $colorParser,
20
        protected IStyleOptionsParser $optionsParser,
21
    ) {
22
    }
23
24
    public function convert(IStyle $style): string
25
    {
26
        if ($style->isEmpty()) {
27
            return $style->getFormat();
28
        }
29
30
        return $this->doConvert($style);
31
    }
32
33
    private function doConvert(IStyle $style): string
34
    {
35
        $fg = $this->fg($style);
36
        $bg = $this->bg($style);
37
38
        $options =
39
            $style->hasOptions()
40
                ? $this->optionsParser->parseOptions($style->getOptions())
41
                : [];
42
43
        return
44
            $this->set($fg, $bg, $options)
45
            . $style->getFormat()
46
            . $this->unset($fg, $bg, $options);
47
    }
48
49
    private function fg(IStyle $style): string
50
    {
51
        $parsed = $this->colorParser->parseColor($style->getFgColor());
52
        return $parsed === '' ? '' : '3' . $parsed;
53
    }
54
55
    private function bg(IStyle $style): string
56
    {
57
        $parsed = $this->colorParser->parseColor($style->getBgColor());
58
        return $parsed === '' ? '' : '4' . $parsed;
59
    }
60
61
    private function set(string $fg, string $bg, iterable $options = []): string
62
    {
63
        $codes = [];
64
        if ($fg !== '') {
65
            $codes[] = $fg;
66
        }
67
        if ($bg !== '') {
68
            $codes[] = $bg;
69
        }
70
        foreach ($options as $option) {
71
            $codes[] = $option[self::SET];
72
        }
73
        if ($codes === []) {
74
            return '';
75
        }
76
77
        return $this->unwrap($codes);
78
    }
79
80
    private function unwrap(array $codes): string
81
    {
82
        return sprintf("\033[%sm", implode(';', array_unique($codes)));
83
    }
84
85
    public function unset(string $fg, string $bg, iterable $options = []): string
86
    {
87
        $codes = [];
88
        if ($fg !== '') {
89
            $codes[] = 39;
90
        }
91
        if ($bg !== '') {
92
            $codes[] = 49;
93
        }
94
        foreach ($options as $option) {
95
            $codes[] = $option[self::UNSET];
96
        }
97
        if ($codes === []) {
98
            return '';
99
        }
100
101
        return $this->unwrap($codes);
102
    }
103
}
104