-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathEnumHelper.php
More file actions
113 lines (93 loc) · 3.52 KB
/
Copy pathEnumHelper.php
File metadata and controls
113 lines (93 loc) · 3.52 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
<?php
/**
* Datetime: 18.10.2018 19:27
* @author Timur Kasumov aka XAKEPEHOK
*/
namespace XAKEPEHOK\EnumHelper;
use Exception;
use XAKEPEHOK\EnumHelper\Exception\ForgottenSwitchCaseException;
use XAKEPEHOK\EnumHelper\Exception\NotEqualsAssociationException;
use XAKEPEHOK\EnumHelper\Exception\OutOfEnumException;
use XAKEPEHOK\EnumHelper\Exception\UnexpectedSwitchCaseValueException;
abstract class EnumHelper
{
/**
* @param mixed $case value, used for switch expression
* @param callable[]|array $switchCaseOrCallbacks associative array like 'case' => callback()
* @param callable|null $caseConvert, callback, which can convert value to $switchCaseCallbacks array
* @return mixed
* @throws ForgottenSwitchCaseException
* @throws UnexpectedSwitchCaseValueException
*/
public static function switchCase($case, array $switchCaseOrCallbacks, callable $caseConvert = null)
{
if (is_null($caseConvert)) {
$caseConvert = static::caseConvertCallback();
}
$diffNotExists = array_diff(static::values(), array_keys($switchCaseOrCallbacks));
if (!empty($diffNotExists)) {
throw new ForgottenSwitchCaseException(implode(", ", $diffNotExists), 1);
}
$diffRedundant = array_diff(array_keys($switchCaseOrCallbacks), static::values());
if (!empty($diffRedundant)) {
throw new ForgottenSwitchCaseException(implode(", ", $diffRedundant), 2);
}
$caseConverted = $caseConvert($case);
foreach ($switchCaseOrCallbacks as $key => $callbackOrValue) {
if ($key == $caseConverted) {
$isCallback = is_callable($callbackOrValue) && !is_string($callbackOrValue);
return $isCallback ? $callbackOrValue($case) : $callbackOrValue;
}
}
throw new UnexpectedSwitchCaseValueException('Unexpected value "' . $caseConverted . '"');
}
/**
* @param array $array
* @param callable|null $keysConvert
* @return array
* @throws NotEqualsAssociationException
*/
public static function associative(array $array, callable $keysConvert = null)
{
if ($keysConvert === null) {
$keysConvert = function ($key) {
return $key;
};
}
$diffNotExists = array_diff(static::values(), array_keys($array));
if (!empty($diffNotExists)) {
throw new NotEqualsAssociationException(implode(", ", $diffNotExists), 1);
}
$diffRedundant = array_diff(array_keys($array), static::values());
if (!empty($diffRedundant)) {
throw new NotEqualsAssociationException(implode(", ", $diffRedundant), 2);
}
$result = [];
foreach ($array as $key => $value) {
$result[$keysConvert($key)] = $value;
}
return $result;
}
public static function caseConvertCallback(): callable
{
return function ($value) {
return $value;
};
}
public static function isValid($value): bool
{
return in_array($value, static::values(), false);
}
/**
* @param $value
* @param Exception|null $exception
* @throws OutOfEnumException
*/
public static function guardValidValue($value, Exception $exception = null)
{
if (!static::isValid($value)) {
throw $exception ?? new OutOfEnumException("Value '{$value}' is not in enum list of class " . static::class);
}
}
abstract public static function values(): array;
}