Passed
Push — master ( 6b639b...2bf033 )
by Alec
01:40
created

AbstractSpinner   A

Complexity

Total Complexity 17

Size/Duplication

Total Lines 145
Duplicated Lines 0 %

Test Coverage

Coverage 94.23%

Importance

Changes 0
Metric Value
eloc 61
dl 0
loc 145
ccs 49
cts 52
cp 0.9423
rs 10
c 0
b 0
f 0
wmc 17

11 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 12 1
A erase() 0 3 1
A inline() 0 6 2
A begin() 0 3 1
A end() 0 3 1
A getStyles() 0 22 3
A refineMessage() 0 6 2
A setFields() 0 5 1
A spin() 0 3 1
A work() 0 3 1
A getStyle() 0 18 3
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 AlecRabbit\Spinner\Contracts\SpinnerInterface;
9
10
abstract class AbstractSpinner implements SpinnerInterface
11
{
12
    protected const ESC = ConsoleColor::ESC_CHAR;
13
    protected const ERASING_SHIFT = 1;
14
15
    /** @var Circular */
16
    protected $spinnerSymbols;
17
    /** @var null|Circular */
18
    protected $styles;
19
    /** @var string */
20
    protected $message;
21
    /** @var string */
22
    protected $moveBackStr;
23
    /** @var \Closure */
24
    protected $style;
25
    /** @var string */
26
    protected $paddingStr;
27
    /** @var string */
28
    protected $eraseBySpacesStr;
29
30
31 8
    public function __construct(
32
        ?string $message = null,
33
        ?string $prefix = null,
34
        ?string $suffix = null,
35
        ?string $paddingStr = null
36
    ) {
37 8
        $this->spinnerSymbols = $this->getSymbols();
38 8
        $this->styles = $this->getStyles();
39 8
        $this->paddingStr = $paddingStr ?? SpinnerInterface::PADDING_NEXT_LINE;
40 8
        $this->message = $this->refineMessage($message, $prefix, $suffix);
41 8
        $this->setFields();
42 8
        $this->style = $this->getStyle();
43 8
    }
44
45
    /**
46
     * @return Circular
47
     */
48
    abstract protected function getSymbols(): Circular;
49
50 4
    protected function getStyles(): ?Circular
51
    {
52 4
        $terminal = new Terminal();
53 4
        if ($terminal->supports256Color()) {
54
            return new Circular([
55
                '38;5;197',
56
                '38;5;198',
57
                '38;5;199',
58
                '38;5;200',
59
                '38;5;201',
60
                '38;5;202',
61
                '38;5;203',
62
                '38;5;204',
63
                '38;5;205',
64
            ]);
65
        }
66 4
        if ($terminal->supportsColor()) {
67 4
            return new Circular([
68 4
                '96',
69
            ]);
70
        }
71
        return null;
72
    }
73
74
    /**
75
     * @param null|string $message
76
     * @param null|string $prefix
77
     * @param null|string $suffix
78
     * @return string
79
     */
80 8
    protected function refineMessage(?string $message, ?string $prefix, ?string $suffix): string
81
    {
82 8
        $message = ucfirst($message ?? SpinnerInterface::DEFAULT_MESSAGE);
83 8
        $prefix = $prefix ?? SpinnerInterface::DEFAULT_PREFIX;
84 8
        $suffix = $suffix ?? (empty($message) ? '' : SpinnerInterface::DEFAULT_SUFFIX);
85 8
        return $prefix . $message . $suffix;
86
    }
87
88
    /**
89
     * @return \Closure
90
     */
91 8
    protected function getStyle(): \Closure
92
    {
93 8
        if (null === $this->styles) {
94
            return
95
                function (): string {
96 2
                    $value = (string)$this->spinnerSymbols->value();
97 2
                    return $this->paddingStr . $value;
98 2
                };
99
        }
100
        return
101
            function (): string {
102 6
                $symbol = (string)$this->spinnerSymbols->value();
103 6
                $style = $this->styles ? (string)$this->styles->value() : '';
104
                return
105 6
                    $this->paddingStr .
106 6
                    self::ESC .
107 6
                    "[{$style}m{$symbol}" .
108 6
                    self::ESC . '[0m';
109 6
            };
110
    }
111
112 1
    public function inline(bool $inline): SpinnerInterface
113
    {
114 1
        $this->paddingStr = $inline ? SpinnerInterface::PADDING_INLINE : SpinnerInterface::PADDING_NEXT_LINE;
115 1
        $this->setFields();
116
117 1
        return $this;
118
    }
119
120
    /** {@inheritDoc} */
121 8
    public function begin(): string
122
    {
123 8
        return $this->spin();
124
    }
125
126 8
    protected function work(): string
127
    {
128 8
        return ($this->style)() . $this->message;
129
    }
130
131
    /** {@inheritDoc} */
132 8
    public function spin(): string
133
    {
134 8
        return $this->work() . $this->moveBackStr;
135
    }
136
137
    /** {@inheritDoc} */
138 8
    public function end(): string
139
    {
140 8
        return $this->erase();
141
//        return self::ESC . '[K';
142
    }
143
144
    /** {@inheritDoc} */
145 8
    public function erase(): string
146
    {
147 8
        return $this->eraseBySpacesStr . $this->moveBackStr;
148
    }
149
150 8
    protected function setFields(): void
151
    {
152 8
        $strLen = strlen($this->message . $this->paddingStr) + static::ERASING_SHIFT;
153 8
        $this->moveBackStr = self::ESC . "[{$strLen}D";
154 8
        $this->eraseBySpacesStr = str_repeat(' ', $strLen);
155 8
    }
156
}
157