-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathCollectionBase.php
More file actions
122 lines (107 loc) · 3.47 KB
/
CollectionBase.php
File metadata and controls
122 lines (107 loc) · 3.47 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
114
115
116
117
118
119
120
121
122
<?php
declare(strict_types=1);
namespace WizDevelop\PhpValueObject\Collection\Base;
use Override;
use Stringable;
use WizDevelop\PhpMonad\Result;
use WizDevelop\PhpValueObject\Error\ValueObjectError;
use WizDevelop\PhpValueObject\IValueObject;
use WizDevelop\PhpValueObject\Utils;
use function count;
/**
* 不変コレクション
* @template TKey
* @template TValue
*/
abstract readonly class CollectionBase implements IValueObject, Stringable
{
final protected const int MIN_COUNT = 0;
final protected const int MAX_COUNT = 99999999;
/**
* @param array<TKey,TValue> $elements
*/
protected function __construct(protected array $elements)
{
Utils::assertResultIsOk(static::isValid($elements));
Utils::assertResultIsOk(static::isValidCount($elements));
}
#[Override]
final public function equals(IValueObject $other): bool
{
return (string)$this === (string)$other;
}
#[Override]
final public function __toString(): string
{
return json_encode($this->jsonSerialize(), JSON_THROW_ON_ERROR);
}
/**
* @return array<TKey,TValue>
*/
#[Override]
final public function jsonSerialize(): array
{
return $this->elements;
}
/**
* 要素数の下限値
* NOTE: 実装クラスでのオーバーライド用メソッド
* @return positive-int|0
*/
abstract protected static function minCount(): int;
/**
* 要素数の上限値
* NOTE: 実装クラスでのオーバーライド用メソッド
* @return positive-int
*/
abstract protected static function maxCount(): int;
/**
* 要素数が有効か
* @template TIsValidCountKey of TKey|array-key
* @template TIsValidCountValue of TValue
* @param array<TIsValidCountKey,TIsValidCountValue> $elements
* @return Result<bool,ValueObjectError>
*/
final protected static function isValidCount(array $elements): Result
{
$element_count = count($elements);
$min_count = static::minCount() > self::MIN_COUNT ? static::minCount() : self::MIN_COUNT;
$max_count = static::maxCount() < self::MAX_COUNT ? static::maxCount() : self::MAX_COUNT;
if ($element_count < $min_count && $element_count > $max_count) {
return Result\err(ValueObjectError::collection()->invalidRange(
className: static::class,
min: $min_count,
max: $max_count,
count: $element_count,
));
}
if ($element_count < $min_count) {
return Result\err(ValueObjectError::collection()->invalidMinCount(
className: static::class,
min: $min_count,
count: $element_count,
));
}
if ($element_count > $max_count) {
return Result\err(ValueObjectError::collection()->invalidMaxCount(
className: static::class,
max: $max_count,
count: $element_count,
));
}
return Result\ok(true);
}
/**
* 有効な値かどうか
* NOTE: 実装クラスでのオーバーライド用メソッド
*
* @template TIsValidKey of TKey|array-key
* @template TIsValidValue of TValue
* @param array<TIsValidKey,TIsValidValue> $elements
* @return Result<bool,ValueObjectError>
*/
protected static function isValid(array $elements): Result
{
return Result\ok(true);
}
}