Lines
100.00%
13 / 13
Methods
100.00%
5 / 5
Classes
100.00%
1 / 1
| Name | Lines | Methods | CRAP | ||||
|---|---|---|---|---|---|---|---|
| __construct | 100.00% | 1 / 1 | 100.00% | 1 / 1 | 1 | ||
| claim | 100.00% | 7 / 7 | 100.00% | 1 / 1 | 3 | ||
| claimExactly | 100.00% | 3 / 3 | 100.00% | 1 / 1 | 3 | ||
| isReserved | 100.00% | 1 / 1 | 100.00% | 1 / 1 | 1 | ||
| isTaken | 100.00% | 1 / 1 | 100.00% | 1 / 1 | 1 | ||
| 9 | final class IdentifierAllocator | |
| 10 | { | |
| 11 | /** @var array<string, true> */ | |
| 12 | private array $taken = []; | |
| 13 | ||
| 14 | /** @param list<string> $reserved */ | |
| 15 | public function __construct( | |
| 16 | private readonly array $reserved, | |
| 17 | private readonly string $suffix, | |
| 18 | ) {} | |
| 19 | ||
| 20 | public function claim(string $preferred): string | |
| 21 | { | |
| 22 | $base = $this->isReserved($preferred) ? $preferred . $this->suffix : $preferred; | |
| 23 | $candidate = $base; | |
| 24 | $attempt = 1; | |
| 25 | ||
| 26 | while ($this->isTaken($candidate)) { | |
| 27 | $candidate = $base . ++$attempt; | |
| 28 | } | |
| 29 | ||
| 30 | $this->taken[strtolower($candidate)] = true; | |
| 31 | ||
| 32 | return $candidate; | |
| 33 | } | |
| 34 | ||
| 35 | public function claimExactly(string $name): void | |
| 36 | { | |
| 37 | if ($this->isReserved($name) || $this->isTaken($name)) { | |
| 38 | throw new LogicException(\sprintf('%s is not free to claim.', $name)); | |
| 39 | } | |
| 40 | ||
| 41 | $this->taken[strtolower($name)] = true; | |
| 42 | } | |
| 43 | ||
| 44 | public function isReserved(string $name): bool | |
| 45 | { | |
| 46 | return \in_array(strtolower($name), array_map(strtolower(...), $this->reserved), true); | |
| 47 | } | |
| 48 | ||
| 49 | private function isTaken(string $name): bool | |
| 50 | { | |
| 51 | return isset($this->taken[strtolower($name)]); | |
| 52 | } | |
| 53 | } |