Passed
Push — master ( f46582...923fc3 )
by Alec
02:06
created

Styling::message()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

Changes 0
Metric Value
eloc 4
dl 0
loc 6
ccs 4
cts 4
cp 1
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
crap 1
1
<?php declare(strict_types=1);
2
3
namespace AlecRabbit\Spinner\Core;
4
5
use AlecRabbit\Accessories\Circular;
6
use AlecRabbit\ConsoleColour\ConsoleColor;
7
use AlecRabbit\ConsoleColour\Terminal;
8
9
/**
10
 * Class Styling
11
 */
12
class Styling
13
{
14
    public const COLOR256_SPINNER_STYLES = '256_color_spinner_styles';
15
    public const COLOR_SPINNER_STYLES = 'color_spinner_styles';
16
17
    public const COLOR_MESSAGE_STYLES = 'color_message_styles';
18
    public const COLOR_PERCENT_STYLES = 'color_percent_styles';
19
20
    public const DEFAULT_MESSAGE_STYLES = [2];
21
    public const DEFAULT_PERCENT_STYLES = [2];
22
23
    public const MAX_SYMBOLS_COUNT = 50;
24
25
    /** @var Circular */
26
    protected $symbolStyles;
27
    /** @var Circular */
28
    protected $messageStyles;
29
    /** @var Circular */
30
    protected $percentStyles;
31
    /** @var Circular */
32
    protected $symbols;
33
34 9
    public function __construct(array $symbols, array $styles)
35
    {
36 9
        $this->assertSymbols($symbols);
37 9
        $this->assertStyles($styles);
38 9
        $this->symbols = new Circular($symbols);
39 9
        $this->symbolStyles = $this->symbolStyles($styles);
40 9
        $this->messageStyles = $this->messageStyles($styles);
41 9
        $this->percentStyles = $this->percentStyles($styles);
42 9
    }
43
44 9
    protected function assertSymbols(array $symbols): void
45
    {
46 9
        if (self::MAX_SYMBOLS_COUNT < count($symbols)) {
47
            throw new \InvalidArgumentException('Symbols array is too big.');
48
        }
49 9
    }
50
51 9
    protected function assertStyles(array $styles): void
52
    {
53 9
        if (!\array_key_exists(self::COLOR256_SPINNER_STYLES, $styles)) {
54
            throw new \InvalidArgumentException(
55
                $this->errorMsg('Styles array does not have', 'COLOR256_STYLES')
56
            );
57
        }
58 9
        $value = $styles[self::COLOR256_SPINNER_STYLES];
59 9
        if (!\is_array($value) && null !== $value) {
60
            throw new \InvalidArgumentException(
61
                $this->errorMsg('Styles should be type of array or NULL in', 'COLOR256_STYLES')
62
            );
63
        }
64 9
        if (!\array_key_exists(self::COLOR_SPINNER_STYLES, $styles)) {
65
            throw new \InvalidArgumentException(
66
                $this->errorMsg('Styles array does not have', 'COLOR_STYLES')
67
            );
68
        }
69 9
        $value = $styles[self::COLOR_SPINNER_STYLES];
70 9
        if (!is_array($value) && null !== $value) {
71
            throw new \InvalidArgumentException(
72
                $this->errorMsg('Styles should be type of array or NULL in', 'COLOR_SPINNER_STYLES')
73
            );
74
        }
75 9
    }
76
77
    /**
78
     * @param string $str
79
     * @param string $constant
80
     * @return string
81
     */
82
    private function errorMsg(string $str, string $constant): string
83
    {
84
        return $str . ' ' . $constant . ' key.';
85
    }
86
87
    /**
88
     * @param array $styles
89
     * @return Circular
90
     */
91 9
    protected function symbolStyles(array $styles): Circular
92
    {
93 9
        $value = $styles[self::COLOR256_SPINNER_STYLES];
94
        /** @noinspection NotOptimalIfConditionsInspection */
95 9
        if (($terminal = new Terminal())->supports256Color() && null !== $value) {
96
            return $this->circular256Color($value);
97
        }
98
99 9
        $value = $styles[self::COLOR_SPINNER_STYLES];
100
        /** @noinspection NotOptimalIfConditionsInspection */
101 9
        if ($terminal->supportsColor() && null !== $value) {
102 6
            return $this->circularColor($value);
103
        }
104 3
        return $this->circularNoColor();
105
    }
106
107
    protected function circular256Color(array $styles): Circular
108
    {
109
        return
110
            new Circular(
111
                array_map(
112
                    static function (string $value): string {
113
                        return ConsoleColor::ESC_CHAR . "[38;5;{$value}m%s" . ConsoleColor::ESC_CHAR . '[0m';
114
                    },
115
                    $styles
116
                )
117
            );
118
    }
119
120 9
    protected function circularColor(array $styles): Circular
121
    {
122
        return
123 9
            new Circular(
124 9
                array_map(
125
                    static function (string $value): string {
126 9
                        return ConsoleColor::ESC_CHAR . "[{$value}m%s" . ConsoleColor::ESC_CHAR . '[0m';
127 9
                    },
128 9
                    $styles
129
                )
130
            );
131
    }
132
133 3
    protected function circularNoColor(): Circular
134
    {
135 3
        return new Circular(['%s',]);
136
    }
137
138
    /**
139
     * @param array $styles
140
     * @return Circular
141
     */
142 9
    protected function messageStyles(array $styles): Circular
143
    {
144 9
        if (!\array_key_exists(self::COLOR_MESSAGE_STYLES, $styles)) {
145 9
            $styles[self::COLOR_MESSAGE_STYLES] = self::DEFAULT_MESSAGE_STYLES;
146
        }
147 9
        if ((new Terminal())->supportsColor()) {
148 9
            $value = $styles[self::COLOR_MESSAGE_STYLES];
149 9
            if (null === $value) {
150
                return $this->circularNoColor();
151
            }
152 9
            return $this->circularColor($value);
153
        }
154
        return $this->circularNoColor();
155
    }
156
157
    /**
158
     * @param array $styles
159
     * @return Circular
160
     */
161 9
    protected function percentStyles(array $styles): Circular
162
    {
163 9
        if (!\array_key_exists(self::COLOR_PERCENT_STYLES, $styles)) {
164 9
            $styles[self::COLOR_PERCENT_STYLES] = self::DEFAULT_PERCENT_STYLES;
165
        }
166 9
        if ((new Terminal())->supportsColor()) {
167 9
            $value = $styles[self::COLOR_PERCENT_STYLES];
168 9
            if (null === $value) {
169
                return $this->circularNoColor();
170
            }
171 9
            return $this->circularColor($value);
172
        }
173
        return $this->circularNoColor();
174
    }
175
176 8
    public function spinner(): string
177
    {
178 8
        return sprintf((string)$this->symbolStyles->value(), (string)$this->symbols->value());
179
    }
180
181 8
    public function message(string $message): string
182
    {
183
        return
184 8
            sprintf(
185 8
                (string)$this->messageStyles->value(),
186 8
                $message
187
            );
188
    }
189
190 8
    public function percent(string $percent): string
191
    {
192
        return
193 8
            sprintf(
194 8
                (string)$this->percentStyles->value(),
195 8
                $percent
196
            );
197
    }
198
}
199