Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,17 @@ All notable changes to this project will be documented in this file. This projec

## Next Major Release

### Changed

- **BREAKING**: The `Guid::make()` method will now convert a string that is a UUID to a UUID GUID. Previously it would
use a string id.
- **BREAKING**: Updated the `GuidTypeMap` class so that it now supports enum aliases, enum types, and UUID identifiers.
This means the `type()` method now returns a string or enum, whereas previously it returned just a string.

### Removed

- Package no longer supports PHP 8.1. The minimum supported version is now PHP 8.2.
- **BREAKING**: Remove the `Guid::type()` method - use `enum_value($guid->type)` or `enum_string($guid->type)` instead.

## Unreleased

Expand Down
28 changes: 9 additions & 19 deletions src/Toolkit/Identifiers/Guid.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@
use CloudCreativity\Modules\Contracts\Toolkit\Identifiers\Identifier;
use CloudCreativity\Modules\Toolkit\ContractException;
use CloudCreativity\Modules\Toolkit\Contracts;
use Ramsey\Uuid\Uuid as RamseyUuid;
use Ramsey\Uuid\UuidInterface;
use UnitEnum;

use function CloudCreativity\Modules\Toolkit\enum_string;
use function CloudCreativity\Modules\Toolkit\enum_value;

final readonly class Guid implements Identifier
{
Expand Down Expand Up @@ -76,16 +76,17 @@ public static function fromUuid(UnitEnum|string $type, Uuid|UuidInterface|string
* Create a GUID.
*
* @param UnitEnum|string $type
* @param string|int $id
* @param Uuid|UuidInterface|string|int $id
* @return self
*/
public static function make(UnitEnum|string $type, string|int $id): self
public static function make(UnitEnum|string $type, Uuid|UuidInterface|string|int $id): self
{
if (is_int($id)) {
return self::fromInteger($type, $id);
}

return self::fromString($type, $id);
return match (true) {
$id instanceof Uuid, $id instanceof UuidInterface, is_string($id) && RamseyUuid::isValid($id)
=> self::fromUuid($type, $id),
is_string($id) => self::fromString($type, $id),
is_int($id) => self::fromInteger($type, $id),
};
}

/**
Expand Down Expand Up @@ -200,15 +201,4 @@ enum_string($this->type),

return $this;
}

/**
* Get the type expressed as a string or an integer.
*
* @return string|int
*/
public function type(): string|int
{
// TODO 4.0 use enum_string() instead
return enum_value($this->type);
}
}
39 changes: 30 additions & 9 deletions src/Toolkit/Identifiers/GuidTypeMap.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,37 +12,58 @@

namespace CloudCreativity\Modules\Toolkit\Identifiers;

final readonly class GuidTypeMap
use Ramsey\Uuid\UuidInterface;
use UnitEnum;

use function CloudCreativity\Modules\Toolkit\enum_string;

final class GuidTypeMap
{
/**
* GuidTypeMap constructor
*
* @param array<string, mixed> $map
*/
public function __construct(private array $map)
public function __construct(private array $map = [])
{
}

/**
* Define an alias to type mapping.
*
* @param UnitEnum|string $alias
* @param UnitEnum|string $type
* @return void
*/
public function define(UnitEnum|string $alias, UnitEnum|string $type): void
{
$alias = enum_string($alias);

$this->map[$alias] = $type;
}

/**
* Get the GUID for the specified alias and id.
*
* @param string $alias
* @param string|int $id
* @param UnitEnum|string $alias
* @param Uuid|UuidInterface|string|int $id
* @return Guid
*/
public function guidFor(string $alias, string|int $id): Guid
public function guidFor(UnitEnum|string $alias, Uuid|UuidInterface|string|int $id): Guid
{
return Guid::make($this->typeFor($alias), $id);
}

/**
* Get the GUID type for the specified alias.
*
* @param string $alias
* @return string
* @param UnitEnum|string $alias
* @return UnitEnum|string
*/
public function typeFor(string $alias): string
public function typeFor(UnitEnum|string $alias): UnitEnum|string
{
$alias = enum_string($alias);

assert(
isset($this->map[$alias]),
sprintf('Alias "%s" is not defined in the type map.', $alias),
Expand All @@ -51,7 +72,7 @@ public function typeFor(string $alias): string
$type = $this->map[$alias] ?? null;

assert(
is_string($type) && !empty($type),
(is_string($type) || $type instanceof UnitEnum) && !empty($type),
sprintf('Expecting type for alias "%s" to be a non-empty string.', $alias),
);

Expand Down
26 changes: 25 additions & 1 deletion tests/Unit/Toolkit/Identifiers/GuidTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

namespace CloudCreativity\Modules\Tests\Unit\Toolkit\Identifiers;

use CloudCreativity\Modules\Contracts\Toolkit\Identifiers\Identifier;
use CloudCreativity\Modules\Tests\TestBackedEnum;
use CloudCreativity\Modules\Tests\TestUnitEnum;
use CloudCreativity\Modules\Toolkit\ContractException;
Expand All @@ -22,6 +23,7 @@
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
use Ramsey\Uuid\Uuid as BaseUuid;
use Ramsey\Uuid\UuidInterface;
use UnitEnum;

class GuidTest extends TestCase
Expand Down Expand Up @@ -61,7 +63,6 @@ public function testStringId(UnitEnum|string $type, string $value, UnitEnum|stri

$this->assertInstanceOf(\Stringable::class, $guid);
$this->assertSame($type, $guid->type);
$this->assertSame($value, $guid->type());
$this->assertObjectEquals(new StringId('123'), $guid->id);
$this->assertSame($value . ':123', $guid->toString());
$this->assertSame($value . ':123', (string) $guid);
Expand Down Expand Up @@ -135,6 +136,29 @@ public function testUuid(UnitEnum|string $type, string $value, UnitEnum|string $
$this->assertObjectEquals($guid, Guid::fromUuid($type, $uuid->value));
}

/**
* @return array<string, array{0: Uuid|UuidInterface|string|int, 1: Identifier}>
*/
public static function makeProvider(): array
{
$uuid = Uuid::random();

return [
'integer' => [123, new IntegerId(123)],
'string' => ['some-slug', new StringId('some-slug')],
'ramsey uuid' => [$uuid->value, $uuid],
'uuid object' => [$uuid, $uuid],
'string uuid' => [$uuid->toString(), $uuid],
];
}

#[DataProvider('makeProvider')]
public function testItMakesGuid(Uuid|UuidInterface|string|int $value, Identifier $expected): void
{
$guid = Guid::make('SomeType', $value);
$this->assertObjectEquals($expected, $guid->id);
}

/**
* @return void
*/
Expand Down
27 changes: 24 additions & 3 deletions tests/Unit/Toolkit/Identifiers/GuidTypeMapTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,17 @@
namespace CloudCreativity\Modules\Tests\Unit\Toolkit\Identifiers;

use AssertionError;
use CloudCreativity\Modules\Tests\TestBackedEnum;
use CloudCreativity\Modules\Tests\TestBackedIntEnum;
use CloudCreativity\Modules\Tests\TestUnitEnum;
use CloudCreativity\Modules\Toolkit\Identifiers\Guid;
use CloudCreativity\Modules\Toolkit\Identifiers\GuidTypeMap;
use CloudCreativity\Modules\Toolkit\Identifiers\Uuid;
use PHPUnit\Framework\Attributes\Depends;
use PHPUnit\Framework\TestCase;

class GuidTypeMapTest extends TestCase
{
/**
* @return GuidTypeMap
*/
public function testItReturnsExpectedType(): GuidTypeMap
{
$map = new GuidTypeMap([
Expand Down Expand Up @@ -80,4 +81,24 @@ public function testItThrowsIfTypeIsNotDefined(GuidTypeMap $map): void

$map->typeFor('NotDefined');
}

public function testItReturnsExpectedTypeWithEnums(): void
{
$map = new GuidTypeMap();
$map->define(TestBackedEnum::Foo, 'SomeFooType');
$map->define(TestBackedEnum::Bar, TestBackedIntEnum::FooBar);
$map->define(TestUnitEnum::Baz, 'SomeBazType');
$map->define(TestUnitEnum::Bat, TestBackedIntEnum::BazBat);

$id = Uuid::random();

$this->assertSame('SomeFooType', $map->typeFor(TestBackedEnum::Foo));
$this->assertObjectEquals(Guid::fromUuid('SomeFooType', $id), $map->guidFor(TestBackedEnum::Foo, $id));
$this->assertSame(TestBackedIntEnum::FooBar, $map->typeFor(TestBackedEnum::Bar));
$this->assertObjectEquals(Guid::fromUuid(TestBackedIntEnum::FooBar, $id), $map->guidFor(TestBackedEnum::Bar, $id));
$this->assertSame('SomeBazType', $map->typeFor(TestUnitEnum::Baz));
$this->assertObjectEquals(Guid::fromUuid('SomeBazType', $id), $map->guidFor(TestUnitEnum::Baz, $id));
$this->assertSame(TestBackedIntEnum::BazBat, $map->typeFor(TestUnitEnum::Bat));
$this->assertObjectEquals(Guid::fromUuid(TestBackedIntEnum::BazBat, $id), $map->guidFor(TestUnitEnum::Bat, $id));
}
}