Passed
Push — master ( 4de5b6...25cee1 )
by Alec
01:45
created

AbstractSpinner::work()   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
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
rs 10
c 0
b 0
f 0
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
        // @codeCoverageIgnoreStart
67
        if ($terminal->supportsColor()) {
68
            return new Circular([
69
                '96',
70
            ]);
71
        }
72
        return null;
73
        // @codeCoverageIgnoreEnd
74
    }
75
76
    /**
77
     * @param null|string $message
78
     * @param null|string $prefix
79
     * @param null|string $suffix
80
     * @return string
81
     */
82 8
    protected function refineMessage(?string $message, ?string $prefix, ?string $suffix): string
83
    {
84 8
        $message = ucfirst($message ?? SpinnerInterface::DEFAULT_MESSAGE);
85 8
        $prefix = $prefix ?? SpinnerInterface::DEFAULT_PREFIX;
86 8
        $suffix = $suffix ?? (empty($message) ? '' : SpinnerInterface::DEFAULT_SUFFIX);
87 8
        return $prefix . $message . $suffix;
88
    }
89
90
    /**
91
     * @return \Closure
92
     */
93 8
    protected function getStyle(): \Closure
94
    {
95 8
        if (null === $this->styles) {
96
            return
97
                function (): string {
98 2
                    $value = (string)$this->spinnerSymbols->value();
99 2
                    return $this->paddingStr . $value;
100 2
                };
101
        }
102
        return
103
            function (): string {
104 6
                $symbol = (string)$this->spinnerSymbols->value();
105 6
                $style = $this->styles ? (string)$this->styles->value() : '';
106
                return
107 6
                    $this->paddingStr .
108 6
                    self::ESC .
109 6
                    "[{$style}m{$symbol}" .
110 6
                    self::ESC . '[0m';
111 6
            };
112
    }
113
114 1
    public function inline(bool $inline): SpinnerInterface
115
    {
116 1
        $this->paddingStr = $inline ? SpinnerInterface::PADDING_INLINE : SpinnerInterface::PADDING_NEXT_LINE;
117 1
        $this->setFields();
118
119 1
        return $this;
120
    }
121
122
    /** {@inheritDoc} */
123 8
    public function begin(): string
124
    {
125 8
        return $this->spin();
126
    }
127
128 8
    protected function work(): string
129
    {
130 8
        return ($this->style)() . $this->message;
131
    }
132
133
    /** {@inheritDoc} */
134 8
    public function spin(): string
135
    {
136 8
        return $this->work() . $this->moveBackStr;
137
    }
138
139
    /** {@inheritDoc} */
140 8
    public function end(): string
141
    {
142 8
        return $this->erase();
143
//        return self::ESC . '[K';
144
    }
145
146
    /** {@inheritDoc} */
147 8
    public function erase(): string
148
    {
149 8
        return $this->eraseBySpacesStr . $this->moveBackStr;
150
    }
151
152 8
    protected function setFields(): void
153
    {
154 8
        $strLen = strlen($this->message . $this->paddingStr) + static::ERASING_SHIFT;
155 8
        $this->moveBackStr = self::ESC . "[{$strLen}D";
156 8
        $this->eraseBySpacesStr = str_repeat(' ', $strLen);
157 8
    }
158
}
159