Passed
Push — master ( d4a0a9...a5fa1a )
by Alec
02:38 queued 13s
created

src/Spinner/Config/A/AConfigBuilder.php (2 issues)

Labels
Severity
1
<?php
2
3
declare(strict_types=1);
4
5
namespace AlecRabbit\Spinner\Config\A;
6
7
use AlecRabbit\Spinner\Config\Config;
8
use AlecRabbit\Spinner\Config\Contract\IConfig;
9
use AlecRabbit\Spinner\Config\Contract\IConfigBuilder;
10
use AlecRabbit\Spinner\Config\Defaults\Contract\IDefaults;
11
use AlecRabbit\Spinner\Core\Contract\IFrame;
12
use AlecRabbit\Spinner\Core\Contract\ITimer;
13
use AlecRabbit\Spinner\Core\Driver;
14
use AlecRabbit\Spinner\Core\Frame;
15
use AlecRabbit\Spinner\Core\Interval;
16
use AlecRabbit\Spinner\Core\Output\Contract\IDriver;
17
use AlecRabbit\Spinner\Core\Output\Contract\IOutput;
18
use AlecRabbit\Spinner\Core\Output\StreamOutput;
19
use AlecRabbit\Spinner\Core\Revolver\Contract\IFrameCollectionRevolver;
20
use AlecRabbit\Spinner\Core\Revolver\Contract\IRevolver;
21
use AlecRabbit\Spinner\Core\Revolver\FrameCollectionRevolver;
22
use AlecRabbit\Spinner\Core\Timer;
23
use AlecRabbit\Spinner\Core\Widget\Contract\IWidgetBuilder;
24
use AlecRabbit\Spinner\Core\Widget\Contract\IWidgetComposite;
25
use AlecRabbit\Spinner\Core\Widget\WidgetRevolver;
26
use AlecRabbit\Spinner\Exception\InvalidArgumentException;
27
use AlecRabbit\Spinner\Exception\LogicException;
28
use AlecRabbit\Spinner\Factory\WidgetFactory;
29
30
abstract class AConfigBuilder implements IConfigBuilder
31
{
32
    protected ?IDriver $driver = null;
33
    protected ?ITimer $timer = null;
34
    protected ?IRevolver $widgetRevolver = null;
35
    protected ?IFrame $leadingSpacer = null;
36
    protected ?IFrame $trailingSpacer = null;
37
    protected ?bool $hideCursor = null;
38
    protected ?bool $createInitialized = null;
39
    protected ?bool $inSynchronousMode = null;
40
    protected ?bool $autoStartEnabled = null;
41
    protected ?bool $signalHandlersEnabled = null;
42
    protected ?string $interruptMessage = null;
43
    protected ?string $finalMessage = null;
44
    protected ?IOutput $output = null;
45
    protected ?IFrameCollectionRevolver $spinnerStyleRevolver = null;
46
    protected ?IFrameCollectionRevolver $spinnerCharRevolver = null;
47
    protected ?int $terminalColorSupport = null;
48
    /** @var array<IWidgetComposite>|null */
49
    protected ?array $widgets = null;
50
    protected ?IWidgetBuilder $widgetBuilder = null;
51
    protected ?IWidgetComposite $mainWidget = null;
52
53
    public function __construct(
54
        protected IDefaults $defaults,
55
    ) {
56
        $this->initializeBuildersAndFactories($this->defaults);
57
    }
58
59
    protected function initializeBuildersAndFactories(IDefaults $defaults): void
60
    {
61
        $this->widgetBuilder = WidgetFactory::getWidgetBuilder();
62
    }
63
64
    public function withMainWidget(IWidgetComposite $widget): self
65
    {
66
        $clone = clone $this;
67
        $clone->mainWidget = $widget;
68
        return $clone;
69
    }
70
71
    public function withInterruptMessage(string $interruptMessage): self
72
    {
73
        $clone = clone $this;
74
        $clone->interruptMessage = $interruptMessage;
75
        return $clone;
76
    }
77
78
    public function withFinalMessage(string $finalMessage): self
79
    {
80
        $clone = clone $this;
81
        $clone->finalMessage = $finalMessage;
82
        return $clone;
83
    }
84
85
    public function withCursor(): self
86
    {
87
        $clone = clone $this;
88
        $clone->hideCursor = false;
89
        return $clone;
90
    }
91
92
    public function withWidgets(array $widgets): self
93
    {
94
        $clone = clone $this;
95
        $clone->widgets = $widgets;
96
        return $clone;
97
    }
98
99
    /**
100
     * @throws LogicException
101
     * @throws InvalidArgumentException
102
     */
103
    public function build(): IConfig
104
    {
105
        $this->processDefaults();
106
107
        return
108
            new Config(
109
                driver: $this->driver,
110
                timer: $this->timer,
111
                mainWidget: $this->mainWidget,
112
                createInitialized: $this->createInitialized,
113
                synchronous: $this->inSynchronousMode,
114
                autoStart: $this->autoStartEnabled,
115
                attachSignalHandlers: $this->signalHandlersEnabled,
116
                widgets: $this->widgets,
117
            );
118
    }
119
120
    /**
121
     * @throws LogicException
122
     * @throws InvalidArgumentException
123
     */
124
    protected function processDefaults(): void
125
    {
126
        $this->timer ??= new Timer();
127
        $this->hideCursor ??= $this->defaults->isHideCursor();
128
        $this->createInitialized ??= $this->defaults->isCreateInitialized();
129
        $this->inSynchronousMode ??= $this->defaults->isModeSynchronous();
130
        $this->autoStartEnabled ??= $this->defaults->isAutoStartEnabled();
131
        $this->signalHandlersEnabled ??= $this->defaults->areSignalHandlersEnabled();
132
        $this->interruptMessage ??= $this->defaults->getInterruptMessage();
133
        $this->finalMessage ??= $this->defaults->getFinalMessage();
134
135
        $this->output ??= $this->createOutput();
136
        $this->driver ??= $this->createDriver();
137
138
        $this->terminalColorSupport ??= $this->driver->getTerminalColorSupport();
139
140
        $this->spinnerStyleRevolver ??=
141
            $this->createSpinnerStyleRevolver(
142
                $this->defaults->getSpinnerStylePattern()
0 ignored issues
show
The method getSpinnerStylePattern() does not exist on AlecRabbit\Spinner\Confi...ults\Contract\IDefaults. It seems like you code against a sub-type of AlecRabbit\Spinner\Confi...ults\Contract\IDefaults such as AlecRabbit\Spinner\Config\Defaults\A\ADefaults. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

142
                $this->defaults->/** @scrutinizer ignore-call */ 
143
                                 getSpinnerStylePattern()
Loading history...
143
            );
144
        $this->spinnerCharRevolver ??=
145
            $this->createSpinnerCharRevolver(
146
                $this->defaults->getSpinnerCharPattern()
0 ignored issues
show
The method getSpinnerCharPattern() does not exist on AlecRabbit\Spinner\Confi...ults\Contract\IDefaults. It seems like you code against a sub-type of AlecRabbit\Spinner\Confi...ults\Contract\IDefaults such as AlecRabbit\Spinner\Config\Defaults\A\ADefaults. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

146
                $this->defaults->/** @scrutinizer ignore-call */ 
147
                                 getSpinnerCharPattern()
Loading history...
147
            );
148
149
        $this->widgetRevolver ??= $this->createWidgetRevolver();
150
        $this->leadingSpacer ??= $this->defaults->getDefaultLeadingSpacer();
151
        $this->trailingSpacer ??= $this->defaults->getDefaultTrailingSpacer();
152
        $this->mainWidget ??= $this->createMainWidget();
153
154
        $this->widgets ??= [];
155
    }
156
157
    protected function createOutput(): IOutput
158
    {
159
        return
160
            new StreamOutput($this->defaults->getOutputStream());
161
    }
162
163
    protected function createDriver(): IDriver
164
    {
165
        return
166
            new Driver(
167
                output: $this->output,
168
                hideCursor: $this->hideCursor,
169
                interruptMessage: $this->interruptMessage,
170
                finalMessage: $this->finalMessage,
171
            );
172
    }
173
174
    /**
175
     * @throws InvalidArgumentException
176
     */
177
    protected function createSpinnerStyleRevolver(array $spinnerStylePattern): IFrameCollectionRevolver
178
    {
179
        $frames = [];
180
        foreach ($spinnerStylePattern as $style) {
181
            $frames[] = new Frame($style, 0);
182
        }
183
        return
184
            new FrameCollectionRevolver($frames, new Interval(360));
185
    }
186
187
    /**
188
     * @throws InvalidArgumentException
189
     */
190
    protected function createSpinnerCharRevolver(array $spinnerCharPattern): IFrameCollectionRevolver
191
    {
192
        $frames = [];
193
        foreach ($spinnerCharPattern as $char) {
194
            $frames[] = new Frame($char, 1);
195
        }
196
        return
197
            new FrameCollectionRevolver($frames, new Interval(80));
198
    }
199
200
    protected function createWidgetRevolver(): IRevolver
201
    {
202
        return
203
            new WidgetRevolver(
204
                style: $this->spinnerStyleRevolver,
205
                character: $this->spinnerCharRevolver,
206
            );
207
    }
208
209
    protected function createMainWidget(): IWidgetComposite
210
    {
211
        return
212
            $this->widgetBuilder
213
                ->withWidgetRevolver($this->widgetRevolver)
214
                ->withLeadingSpacer($this->leadingSpacer)
215
                ->withTrailingSpacer($this->trailingSpacer)
216
                ->build();
217
    }
218
}
219