Passed
Push — master ( dbaa53...0b91ad )
by Alec
02:46
created

Spinner::getMessageStr()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
eloc 1
dl 0
loc 3
c 0
b 0
f 0
ccs 2
cts 2
cp 1
rs 10
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\Pretty;
6
use AlecRabbit\ConsoleColour\ConsoleColor;
7
use AlecRabbit\Control\Cursor;
8
use AlecRabbit\Spinner\Contracts\SettingsInterface;
9
use AlecRabbit\Spinner\Contracts\SpinnerInterface;
10
use AlecRabbit\Spinner\Contracts\SpinnerStyles;
11
use AlecRabbit\Spinner\Contracts\SpinnerSymbols;
12
use AlecRabbit\Spinner\Contracts\StylesInterface;
13
use function AlecRabbit\typeOf;
14
15
class Spinner implements SpinnerInterface
16
{
17
    protected const ERASING_SHIFT = 1;
18
    protected const INTERVAL = 0.125;
19
    protected const SYMBOLS = SpinnerSymbols::DIAMOND;
20
    protected const
21
        STYLES =
22
        [
23
            StylesInterface::COLOR256_SPINNER_STYLES => SpinnerStyles::C256_RAINBOW,
24
            StylesInterface::COLOR_SPINNER_STYLES => SpinnerStyles::C_LIGHT_CYAN,
25
            StylesInterface::COLOR_MESSAGE_STYLES => SpinnerStyles::C_DARK,
26
            StylesInterface::COLOR_PERCENT_STYLES => SpinnerStyles::C_DARK,
27
        ];
28
29
    /** @var string */
30
    protected $messageStr;
31
    /** @var string */
32
    protected $percentStr = '';
33
    /** @var string */
34
    protected $percentPrefix;
35
    /** @var string */
36
    protected $moveBackSequenceStr;
37
    /** @var string */
38
    protected $inlinePaddingStr;
39
    /** @var string */
40
    protected $eraseBySpacesStr;
41
    /** @var Styling */
42
    protected $styled;
43
44
    /**
45
     * AbstractSpinner constructor.
46
     * @param mixed $settings
47
     */
48 10
    public function __construct($settings = null)
49
    {
50 10
        $settings = $this->refineSettings($settings);
51 10
        $this->inlinePaddingStr = $settings->getInlinePaddingStr();
52 10
        $this->messageStr = $this->getMessageStr($settings);
53 10
        $this->setFields();
54 10
        $this->styled = new Styling($settings->getSymbols(), $settings->getStyles());
55 10
    }
56
57
    /**
58
     * @param mixed $settings
59
     * @return Settings
60
     */
61 10
    protected function refineSettings($settings): Settings
62
    {
63 10
        $this->assertSettings($settings);
64 10
        if (\is_string($settings)) {
65
            return
66 8
                $this->defaultSettings()->setMessage($settings);
67
        }
68
        return
69 2
            $settings ?? $this->defaultSettings();
70
    }
71
72
    /**
73
     * @param mixed $settings
74
     */
75 10
    protected function assertSettings($settings): void
76
    {
77 10
        if (null !== $settings && !\is_string($settings) && !$settings instanceof SettingsInterface) {
78
            throw new \InvalidArgumentException(
79
                'Instance of SettingsInterface or string expected ' . typeOf($settings) . ' given.'
80
            );
81
        }
82 10
    }
83
84
    /**
85
     * @return Settings
86
     */
87 9
    protected function defaultSettings(): Settings
88
    {
89
        return
90 9
            (new Settings())
91 9
                ->setInterval(static::INTERVAL)
92 9
                ->setErasingShift(static::ERASING_SHIFT)
93 9
                ->setSymbols(static::SYMBOLS)
94 9
                ->setStyles(static::STYLES);
95
    }
96
97
    /**
98
     * @param Settings $settings
99
     * @return string
100
     */
101 10
    protected function getMessageStr(Settings $settings): string
102
    {
103 10
        return $settings->getPrefix() . ucfirst($settings->getMessage()) . $settings->getSuffix();
104
    }
105
106 10
    protected function setFields(): void
107
    {
108 10
        $this->percentPrefix = $this->getPrefix();
109
        $strLen =
110 10
            strlen($this->message()) + strlen($this->percent()) + strlen($this->inlinePaddingStr) + static::ERASING_SHIFT;
111 10
        $this->moveBackSequenceStr = ConsoleColor::ESC_CHAR . "[{$strLen}D";
112 10
        $this->eraseBySpacesStr = str_repeat(SettingsInterface::ONE_SPACE_SYMBOL, $strLen);
113 10
    }
114
115
    /**
116
     * @return string
117
     */
118 10
    protected function getPrefix(): string
119
    {
120 10
        if (strpos($this->messageStr, SettingsInterface::DEFAULT_SUFFIX)) {
121 9
            return SettingsInterface::ONE_SPACE_SYMBOL;
122
        }
123 1
        return SettingsInterface::EMPTY;
124
    }
125
126
    /**
127
     * @return string
128
     */
129 10
    protected function message(): string
130
    {
131 10
        return $this->messageStr;
132
    }
133
134
    /**
135
     * @return string
136
     */
137 10
    protected function percent(): string
138
    {
139 10
        return $this->percentStr;
140
    }
141
142 1
    public function interval(): float
143
    {
144 1
        return static::INTERVAL;
145
    }
146
147 2
    public function inline(bool $inline): SpinnerInterface
148
    {
149 2
        $this->inlinePaddingStr = $inline ? SettingsInterface::ONE_SPACE_SYMBOL : SettingsInterface::EMPTY;
150 2
        $this->setFields();
151 2
        return $this;
152
    }
153
154
    /** {@inheritDoc} */
155 9
    public function begin(?float $percent = null): string
156
    {
157 9
        return Cursor::hide() . $this->spin($percent);
158
    }
159
160
    /** {@inheritDoc} */
161 9
    public function spin(?float $percent = null): string
162
    {
163 9
        if (null !== $percent) {
164 1
            $this->updatePercent($percent);
165
        }
166
        return
167 9
            $this->inlinePaddingStr .
168 9
            $this->styled->spinner() .
169 9
            $this->styled->message(
170 9
                $this->message()
171
            ) .
172 9
            $this->styled->percent(
173 9
                $this->percent()
174
            ) .
175 9
            $this->moveBackSequenceStr;
176
    }
177
178
    /**
179
     * @param float $percent
180
     */
181 1
    protected function updatePercent(float $percent): void
182
    {
183 1
        if (0 === (int)($percent * 1000) % 10) {
184 1
            $this->percentStr = Pretty::percent($percent, 0, $this->percentPrefix);
185 1
            $this->setFields();
186
        }
187 1
    }
188
189
    /** {@inheritDoc} */
190 8
    public function end(): string
191
    {
192 8
        return $this->erase() . Cursor::show();
193
    }
194
195
    /** {@inheritDoc} */
196 8
    public function erase(): string
197
    {
198 8
        return $this->eraseBySpacesStr . $this->moveBackSequenceStr;
199
    }
200
}
201