diff --git a/CHANGELOG.md b/CHANGELOG.md index 2859beb..aa83df7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## Unreleased +### Added + +* Introduce `Ramsey\Uuid\TimeBasedInterface` to represent any UUID based on a + date/time value. + ### Changed * Remove the following deprecated classes: diff --git a/docs/reference.rst b/docs/reference.rst index 00e27b6..adb98ee 100644 --- a/docs/reference.rst +++ b/docs/reference.rst @@ -9,6 +9,7 @@ Reference reference/uuid reference/uuidinterface + reference/timebasedinterface reference/fields-fieldsinterface reference/rfc4122-uuidinterface reference/rfc4122-fieldsinterface diff --git a/docs/reference/nonstandard-uuidv6.rst b/docs/reference/nonstandard-uuidv6.rst index cc77067..15f6604 100644 --- a/docs/reference/nonstandard-uuidv6.rst +++ b/docs/reference/nonstandard-uuidv6.rst @@ -8,7 +8,8 @@ Nonstandard\\UuidV6 .. php:class:: UuidV6 - Implements :php:interface:`Ramsey\\Uuid\\Rfc4122\\UuidInterface`. + Implements :php:interface:`Ramsey\\Uuid\\Rfc4122\\UuidInterface` and + :php:interface:`Ramsey\\Uuid\\TimeBasedInterface`. While in the Nonstandard sub-namespace, UuidV6 implements the same interface as the RFC 4122 UUIDs. This is because the definition for version 6 UUIDs is @@ -18,11 +19,6 @@ Nonstandard\\UuidV6 `. In addition to providing the methods defined on the interface, this class additionally provides the following methods. - .. php:method:: getDateTime() - - :returns: A date object representing the timestamp associated with the UUID - :returntype: ``\DateTimeInterface`` - .. php:method:: toUuidV1() :returns: A version 1 UUID, converted from this version 6 UUID diff --git a/docs/reference/rfc4122-uuidv1.rst b/docs/reference/rfc4122-uuidv1.rst index c28c27c..3ab0f5d 100644 --- a/docs/reference/rfc4122-uuidv1.rst +++ b/docs/reference/rfc4122-uuidv1.rst @@ -8,13 +8,7 @@ Rfc4122\\UuidV1 .. php:class:: UuidV1 - Implements :php:interface:`Ramsey\\Uuid\\Rfc4122\\UuidInterface`. + Implements :php:interface:`Ramsey\\Uuid\\Rfc4122\\UuidInterface` and + :php:interface:`Ramsey\\Uuid\\TimeBasedInterface`. UuidV1 represents a :ref:`version 1, time-based UUID `. - In addition to providing the methods defined on the interface, this class - additionally provides the following methods. - - .. php:method:: getDateTime() - - :returns: A date object representing the timestamp associated with the UUID. - :returntype: ``\DateTimeInterface`` diff --git a/docs/reference/timebasedinterface.rst b/docs/reference/timebasedinterface.rst new file mode 100644 index 0000000..1af24a1 --- /dev/null +++ b/docs/reference/timebasedinterface.rst @@ -0,0 +1,16 @@ +.. _reference.timebasedinterface: + +================== +TimeBasedInterface +================== + +.. php:namespace:: Ramsey\Uuid + +.. php:interface:: TimeBasedInterface + + Defines functionality for time-based UUIDs. + + .. php:method:: getDateTime() + + :returns: A date object representing the timestamp associated with the UUID. + :returntype: ``\DateTimeInterface`` diff --git a/src/Lazy/LazyUuidFromString.php b/src/Lazy/LazyUuidFromString.php index 0879c54..934b1f9 100644 --- a/src/Lazy/LazyUuidFromString.php +++ b/src/Lazy/LazyUuidFromString.php @@ -16,9 +16,11 @@ namespace Ramsey\Uuid\Lazy; use DateTimeInterface; use Ramsey\Uuid\Converter\NumberConverterInterface; +use Ramsey\Uuid\Exception\UnsupportedOperationException; use Ramsey\Uuid\Fields\FieldsInterface; use Ramsey\Uuid\Nonstandard\UuidV6; use Ramsey\Uuid\Rfc4122\UuidV1; +use Ramsey\Uuid\TimeBasedInterface; use Ramsey\Uuid\Type\Hexadecimal; use Ramsey\Uuid\Type\Integer as IntegerObject; use Ramsey\Uuid\UuidFactory; @@ -51,7 +53,7 @@ use function substr; * @psalm-suppress UndefinedInterfaceMethod * @psalm-suppress DeprecatedMethod */ -final class LazyUuidFromString implements UuidInterface +final class LazyUuidFromString implements UuidInterface, TimeBasedInterface { public const VALID_REGEX = '/\A[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\z/ms'; /** @@ -136,11 +138,15 @@ final class LazyUuidFromString implements UuidInterface ->getNumberConverter(); } - /** @psalm-suppress DeprecatedMethod */ public function getDateTime(): DateTimeInterface { - return ($this->unwrapped ?? $this->unwrap()) - ->getDateTime(); + $unwrapped = ($this->unwrapped ?? $this->unwrap()); + + if ($unwrapped instanceof TimeBasedInterface) { + return $unwrapped->getDateTime(); + } + + throw new UnsupportedOperationException('Not a time-based UUID'); } /** @psalm-suppress DeprecatedMethod */ diff --git a/src/Nonstandard/UuidV6.php b/src/Nonstandard/UuidV6.php index 05586b3..ba71e7c 100644 --- a/src/Nonstandard/UuidV6.php +++ b/src/Nonstandard/UuidV6.php @@ -25,6 +25,7 @@ use Ramsey\Uuid\Lazy\LazyUuidFromString; use Ramsey\Uuid\Rfc4122\FieldsInterface as Rfc4122FieldsInterface; use Ramsey\Uuid\Rfc4122\UuidInterface; use Ramsey\Uuid\Rfc4122\UuidV1; +use Ramsey\Uuid\TimeBasedInterface; use Ramsey\Uuid\Uuid; use Throwable; @@ -43,7 +44,7 @@ use const STR_PAD_LEFT; * * @psalm-immutable */ -final class UuidV6 extends Uuid implements UuidInterface +final class UuidV6 extends Uuid implements UuidInterface, TimeBasedInterface { /** * Creates a version 6 (time-based) UUID @@ -72,13 +73,6 @@ final class UuidV6 extends Uuid implements UuidInterface parent::__construct($fields, $numberConverter, $codec, $timeConverter); } - /** - * Returns a DateTimeInterface object representing the timestamp associated - * with the UUID - * - * @return DateTimeImmutable A PHP DateTimeImmutable instance representing - * the timestamp of a version 6 UUID - */ public function getDateTime(): DateTimeInterface { $time = $this->timeConverter->convertTime($this->fields->getTimestamp()); diff --git a/src/Rfc4122/UuidV1.php b/src/Rfc4122/UuidV1.php index 764e42f..590250e 100644 --- a/src/Rfc4122/UuidV1.php +++ b/src/Rfc4122/UuidV1.php @@ -22,6 +22,7 @@ use Ramsey\Uuid\Converter\TimeConverterInterface; use Ramsey\Uuid\Exception\DateTimeException; use Ramsey\Uuid\Exception\InvalidArgumentException; use Ramsey\Uuid\Rfc4122\FieldsInterface as Rfc4122FieldsInterface; +use Ramsey\Uuid\TimeBasedInterface; use Ramsey\Uuid\Uuid; use Throwable; @@ -35,7 +36,7 @@ use const STR_PAD_LEFT; * * @psalm-immutable */ -final class UuidV1 extends Uuid implements UuidInterface +final class UuidV1 extends Uuid implements UuidInterface, TimeBasedInterface { /** * Creates a version 1 (time-based) UUID @@ -64,16 +65,6 @@ final class UuidV1 extends Uuid implements UuidInterface parent::__construct($fields, $numberConverter, $codec, $timeConverter); } - /** - * Returns a DateTimeInterface object representing the timestamp associated - * with the UUID - * - * The timestamp value is only meaningful in a time-based UUID, which - * has version type 1. - * - * @return DateTimeImmutable A PHP DateTimeImmutable instance representing - * the timestamp of a version 1 UUID - */ public function getDateTime(): DateTimeInterface { $time = $this->timeConverter->convertTime($this->fields->getTimestamp()); diff --git a/src/TimeBasedInterface.php b/src/TimeBasedInterface.php new file mode 100644 index 0000000..091075c --- /dev/null +++ b/src/TimeBasedInterface.php @@ -0,0 +1,30 @@ + + * @license http://opensource.org/licenses/MIT MIT + */ + +declare(strict_types=1); + +namespace Ramsey\Uuid; + +use DateTimeInterface; + +/** + * Time-based UUIDs are derived from a date/time value + * + * @psalm-immutable + */ +interface TimeBasedInterface +{ + /** + * Returns a date object representing the timestamp associated with the UUID + */ + public function getDateTime(): DateTimeInterface; +} diff --git a/tests/UuidTest.php b/tests/UuidTest.php index 715398c..9a70061 100644 --- a/tests/UuidTest.php +++ b/tests/UuidTest.php @@ -253,6 +253,8 @@ class UuidTest extends TestCase // Using a version 4 UUID to test $uuid = Uuid::fromString('bf17b594-41f2-474f-bf70-4c90220f75de'); + $this->assertInstanceOf(LazyUuidFromString::class, $uuid); + $this->expectException(UnsupportedOperationException::class); $this->expectExceptionMessage('Not a time-based UUID');