Passed
Push — master ( 200d88...9b81d7 )
by Alec
02:43 queued 15s
created

Asserter::assertIntColor()   A

Complexity

Conditions 3
Paths 1

Size

Total Lines 37
Code Lines 27

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 27
nc 1
nop 3
dl 0
loc 37
rs 9.488
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
// 15.02.23
5
6
namespace AlecRabbit\Spinner\Helper;
7
8
use AlecRabbit\Spinner\Contract\StyleMode;
9
use AlecRabbit\Spinner\Exception\InvalidArgumentException;
10
use AlecRabbit\Spinner\Exception\RuntimeException;
11
use Traversable;
12
13
use function class_exists;
14
use function extension_loaded;
15
16
final class Asserter
17
{
18
    /**
19
     * @param object|class-string $c
0 ignored issues
show
Documentation Bug introduced by
The doc comment object|class-string at position 2 could not be parsed: Unknown type name 'class-string' at position 2 in object|class-string.
Loading history...
20
     * @param class-string $i
21
     * @param string|null $callerMethod
22
     * @param bool $allowString
23
     * @throws InvalidArgumentException
24
     */
25
    public static function isSubClass(
26
        object|string $c,
27
        string $i,
28
        ?string $callerMethod = null,
29
        bool $allowString = true
30
    ): void {
31
        if (!is_subclass_of($c, $i, $allowString)) {
32
            throw new InvalidArgumentException(
33
                sprintf(
34
                    'Class "%s" must be a subclass of "%s"%s.',
35
                    is_object($c) ? get_class($c) : $c,
36
                    $i,
37
                    self::getSeeMethodStr($callerMethod),
38
                )
39
            );
40
        }
41
    }
42
43
    private static function getSeeMethodStr(?string $callerMethod): string
44
    {
45
        return
46
            $callerMethod
47
                ? sprintf(', see "%s()"', $callerMethod)
48
                : '';
49
    }
50
51
    /**
52
     * @param resource $stream
53
     * @throws InvalidArgumentException
54
     *
55
     */
56
    public static function assertStream(mixed $stream): void
57
    {
58
        /** @psalm-suppress DocblockTypeContradiction */
59
        if (!is_resource($stream) || 'stream' !== get_resource_type($stream)) {
60
            throw new InvalidArgumentException(
61
                sprintf('Argument is expected to be a stream(resource), "%s" given.', get_debug_type($stream))
62
            );
63
        }
64
    }
65
66
    /**
67
     * @throws InvalidArgumentException
68
     */
69
    public static function assertColorModes(Traversable $colorModes): void
70
    {
71
        if (0 === count(iterator_to_array($colorModes))) {
72
            throw new InvalidArgumentException('Color modes must not be empty.');
73
        }
74
        /** @var StyleMode $colorMode */
75
        foreach ($colorModes as $colorMode) {
76
            if (!$colorMode instanceof StyleMode) {
77
                throw new InvalidArgumentException(
78
                    sprintf(
79
                        'Unsupported color mode of type "%s".',
80
                        get_debug_type($colorMode)
81
                    )
82
                );
83
            }
84
        }
85
    }
86
87
    /**
88
     * @throws RuntimeException
89
     */
90
    public static function assertExtensionLoaded(string $extensionName, ?string $message = null): void
91
    {
92
        if (!extension_loaded($extensionName)) {
93
            throw new RuntimeException(
94
                $message ?? sprintf('Extension "%s" is not loaded.', $extensionName)
95
            );
96
        }
97
    }
98
99
    /**
100
     * @throws InvalidArgumentException
101
     */
102
    public static function assertClassExists(string $class, ?string $callerMethod = null): void
103
    {
104
        if (!class_exists($class)) {
105
            throw new InvalidArgumentException(
106
                sprintf(
107
                    'Class "%s" does not exist%s.',
108
                    $class,
109
                    self::getSeeMethodStr($callerMethod)
110
                )
111
            );
112
        }
113
    }
114
115
    /**
116
     * @throws InvalidArgumentException
117
     */
118
    public static function assertHexStringColor(string $entry): void
119
    {
120
        $strlen = strlen($entry);
121
        $entry = strtolower($entry);
122
        match (true) {
123
            0 === $strlen => throw new InvalidArgumentException(
124
                'Value should not be empty string.'
125
            ),
126
            !str_starts_with($entry, '#') => throw new InvalidArgumentException(
127
                sprintf(
128
                    'Value should be a valid hex color code("#rgb", "#rrggbb"), "%s" given. No "#" found.',
129
                    $entry
130
                )
131
            ),
132
            4 !== $strlen && 7 !== $strlen => throw new InvalidArgumentException(
133
                sprintf(
134
                    'Value should be a valid hex color code("#rgb", "#rrggbb"), "%s" given. Length: %d.',
135
                    $entry,
136
                    $strlen
137
                )
138
            ),
139
            default => null,
140
        };
141
    }
142
143
    /**
144
     * @throws InvalidArgumentException
145
     */
146
    public static function assertIntInRange(int $value, int $min, int $max, ?string $callerMethod = null): void
147
    {
148
        match (true) {
149
            $min > $value || $max < $value => throw new InvalidArgumentException(
150
                sprintf(
151
                    'Value should be in range %d..%d, int(%d) given%s.',
152
                    $min,
153
                    $max,
154
                    $value,
155
                    self::getSeeMethodStr($callerMethod)
156
                )
157
            ),
158
            default => null,
159
        };
160
    }
161
162
    /**
163
     * @throws InvalidArgumentException
164
     */
165
    public static function assertIntColor(int $color, StyleMode $styleMode, ?string $callerMethod = null): void
166
    {
167
        match (true) {
168
            0 > $color => throw new InvalidArgumentException(
169
                sprintf(
170
                    'Value should be positive integer, %d given%s.',
171
                    $color,
172
                    self::getSeeMethodStr($callerMethod)
173
                )
174
            ),
175
            StyleMode::ANSI24->name === $styleMode->name => throw new InvalidArgumentException(
0 ignored issues
show
Bug introduced by
The property name does not seem to exist on AlecRabbit\Spinner\Contract\StyleMode.
Loading history...
176
                sprintf(
177
                    'For %s::%s style mode rendering from int is not allowed%s.',
178
                    StyleMode::class,
179
                    StyleMode::ANSI24->name,
180
                    self::getSeeMethodStr($callerMethod)
181
                )
182
            ),
183
            StyleMode::ANSI8->name === $styleMode->name && 255 < $color => throw new InvalidArgumentException(
184
                sprintf(
185
                    'For %s::%s style mode value should be in range 0..255, %d given%s.',
186
                    StyleMode::class,
187
                    StyleMode::ANSI8->name,
188
                    $color,
189
                    self::getSeeMethodStr($callerMethod)
190
                )
191
            ),
192
            StyleMode::ANSI4->name === $styleMode->name && 16 < $color => throw new InvalidArgumentException(
193
                sprintf(
194
                    'For %s::%s style mode value should be in range 0..15, %d given%s.',
195
                    StyleMode::class,
196
                    StyleMode::ANSI4->name,
197
                    $color,
198
                    self::getSeeMethodStr($callerMethod)
199
                )
200
            ),
201
            default => null,
202
        };
203
    }
204
}
205