Passed
Push — master ( 46f5b0...f46582 )
by Alec
02:04
created

Styling::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 1

Importance

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