diff --git a/CHANGELOG.md b/CHANGELOG.md index 4b99293..eb8d693 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -55,9 +55,12 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. * The `UuidInterface::getDateTime()` method now specifies `\DateTimeInterface` as the return value, rather than `\DateTime`; `Uuid::getDateTime()` now returns an instance of `\DateTimeImmutable` instead of `\DateTime`. +* Add `getFields()` method to `UuidInterface`. * Add `getValidator()` method to `UuidFactoryInterface`. * Add `convertTime()` method to `Converter\TimeConverterInterface`. * Add `getTime()` method to `Provider\TimeProviderInterface`. +* Change `Uuid::getFields()` to return an instance of `Fields\FieldsInterface`. + Previously, it returned an array of integer values (on 64-bit systems only). * Introduce `TimeConverterInterface $timeConverter` as fourth required constructor parameter for `Uuid` and second required constructor parameter for `Builder\DefaultUuidBuilder`. diff --git a/src/Guid/Fields.php b/src/Guid/Fields.php index 3705f8a..c6fee6c 100644 --- a/src/Guid/Fields.php +++ b/src/Guid/Fields.php @@ -20,6 +20,7 @@ use Ramsey\Uuid\Rfc4122\FieldsInterface; use Ramsey\Uuid\Rfc4122\NilTrait; use Ramsey\Uuid\Rfc4122\VariantTrait; use Ramsey\Uuid\Rfc4122\VersionTrait; +use Ramsey\Uuid\Type\Hexadecimal; use Ramsey\Uuid\Uuid; /** @@ -76,7 +77,7 @@ final class Fields implements FieldsInterface return $this->bytes; } - public function getTimeLow(): string + public function getTimeLow(): Hexadecimal { // Swap the bytes from little endian to network byte order. $hex = unpack( @@ -88,10 +89,12 @@ final class Fields implements FieldsInterface ) ); - return (string) ($hex[1] ?? ''); + $hex = (string) ($hex[1] ?? ''); + + return new Hexadecimal($hex); } - public function getTimeMid(): string + public function getTimeMid(): Hexadecimal { // Swap the bytes from little endian to network byte order. $hex = unpack( @@ -102,10 +105,12 @@ final class Fields implements FieldsInterface ) ); - return (string) ($hex[1] ?? ''); + $hex = (string) ($hex[1] ?? ''); + + return new Hexadecimal($hex); } - public function getTimeHiAndVersion(): string + public function getTimeHiAndVersion(): Hexadecimal { // Swap the bytes from little endian to network byte order. $hex = unpack( @@ -116,39 +121,41 @@ final class Fields implements FieldsInterface ) ); - return (string) ($hex[1] ?? ''); + $hex = (string) ($hex[1] ?? ''); + + return new Hexadecimal($hex); } - public function getTimestamp(): string + public function getTimestamp(): Hexadecimal { - return sprintf( + return new Hexadecimal(sprintf( '%03x%04s%08s', - hexdec($this->getTimeHiAndVersion()) & 0x0fff, - $this->getTimeMid(), - $this->getTimeLow() - ); + hexdec($this->getTimeHiAndVersion()->toString()) & 0x0fff, + $this->getTimeMid()->toString(), + $this->getTimeLow()->toString() + )); } - public function getClockSeq(): string + public function getClockSeq(): Hexadecimal { $clockSeq = hexdec(bin2hex(substr($this->bytes, 8, 2))) & 0x3fff; - return str_pad(dechex($clockSeq), 4, '0', STR_PAD_LEFT); + return new Hexadecimal(str_pad(dechex($clockSeq), 4, '0', STR_PAD_LEFT)); } - public function getClockSeqHiAndReserved(): string + public function getClockSeqHiAndReserved(): Hexadecimal { - return bin2hex(substr($this->bytes, 8, 1)); + return new Hexadecimal(bin2hex(substr($this->bytes, 8, 1))); } - public function getClockSeqLow(): string + public function getClockSeqLow(): Hexadecimal { - return bin2hex(substr($this->bytes, 9, 1)); + return new Hexadecimal(bin2hex(substr($this->bytes, 9, 1))); } - public function getNode(): string + public function getNode(): Hexadecimal { - return bin2hex(substr($this->bytes, 10)); + return new Hexadecimal(bin2hex(substr($this->bytes, 10))); } public function getVersion(): ?int diff --git a/src/Nonstandard/Fields.php b/src/Nonstandard/Fields.php index 8f56573..40f9af1 100644 --- a/src/Nonstandard/Fields.php +++ b/src/Nonstandard/Fields.php @@ -18,6 +18,7 @@ use Ramsey\Uuid\Exception\InvalidArgumentException; use Ramsey\Uuid\Fields\SerializableFieldsTrait; use Ramsey\Uuid\Rfc4122\FieldsInterface; use Ramsey\Uuid\Rfc4122\VariantTrait; +use Ramsey\Uuid\Type\Hexadecimal; /** * Nonstandard UUID fields do not conform to the RFC 4122 standard @@ -63,51 +64,51 @@ final class Fields implements FieldsInterface return $this->bytes; } - public function getClockSeq(): string + public function getClockSeq(): Hexadecimal { $clockSeq = hexdec(bin2hex(substr($this->bytes, 8, 2))) & 0x3fff; - return str_pad(dechex($clockSeq), 4, '0', STR_PAD_LEFT); + return new Hexadecimal(str_pad(dechex($clockSeq), 4, '0', STR_PAD_LEFT)); } - public function getClockSeqHiAndReserved(): string + public function getClockSeqHiAndReserved(): Hexadecimal { - return bin2hex(substr($this->bytes, 8, 1)); + return new Hexadecimal(bin2hex(substr($this->bytes, 8, 1))); } - public function getClockSeqLow(): string + public function getClockSeqLow(): Hexadecimal { - return bin2hex(substr($this->bytes, 9, 1)); + return new Hexadecimal(bin2hex(substr($this->bytes, 9, 1))); } - public function getNode(): string + public function getNode(): Hexadecimal { - return bin2hex(substr($this->bytes, 10)); + return new Hexadecimal(bin2hex(substr($this->bytes, 10))); } - public function getTimeHiAndVersion(): string + public function getTimeHiAndVersion(): Hexadecimal { - return bin2hex(substr($this->bytes, 6, 2)); + return new Hexadecimal(bin2hex(substr($this->bytes, 6, 2))); } - public function getTimeLow(): string + public function getTimeLow(): Hexadecimal { - return bin2hex(substr($this->bytes, 0, 4)); + return new Hexadecimal(bin2hex(substr($this->bytes, 0, 4))); } - public function getTimeMid(): string + public function getTimeMid(): Hexadecimal { - return bin2hex(substr($this->bytes, 4, 2)); + return new Hexadecimal(bin2hex(substr($this->bytes, 4, 2))); } - public function getTimestamp(): string + public function getTimestamp(): Hexadecimal { - return sprintf( + return new Hexadecimal(sprintf( '%03x%04s%08s', - hexdec($this->getTimeHiAndVersion()) & 0x0fff, - $this->getTimeMid(), - $this->getTimeLow() - ); + hexdec($this->getTimeHiAndVersion()->toString()) & 0x0fff, + $this->getTimeMid()->toString(), + $this->getTimeLow()->toString() + )); } public function getVersion(): ?int diff --git a/src/Rfc4122/Fields.php b/src/Rfc4122/Fields.php index 405313f..a6a5ee0 100644 --- a/src/Rfc4122/Fields.php +++ b/src/Rfc4122/Fields.php @@ -16,6 +16,7 @@ namespace Ramsey\Uuid\Rfc4122; use Ramsey\Uuid\Exception\InvalidArgumentException; use Ramsey\Uuid\Fields\SerializableFieldsTrait; +use Ramsey\Uuid\Type\Hexadecimal; use Ramsey\Uuid\Uuid; /** @@ -74,51 +75,51 @@ final class Fields implements FieldsInterface return $this->bytes; } - public function getClockSeq(): string + public function getClockSeq(): Hexadecimal { $clockSeq = hexdec(bin2hex(substr($this->bytes, 8, 2))) & 0x3fff; - return str_pad(dechex($clockSeq), 4, '0', STR_PAD_LEFT); + return new Hexadecimal(str_pad(dechex($clockSeq), 4, '0', STR_PAD_LEFT)); } - public function getClockSeqHiAndReserved(): string + public function getClockSeqHiAndReserved(): Hexadecimal { - return bin2hex(substr($this->bytes, 8, 1)); + return new Hexadecimal(bin2hex(substr($this->bytes, 8, 1))); } - public function getClockSeqLow(): string + public function getClockSeqLow(): Hexadecimal { - return bin2hex(substr($this->bytes, 9, 1)); + return new Hexadecimal(bin2hex(substr($this->bytes, 9, 1))); } - public function getNode(): string + public function getNode(): Hexadecimal { - return bin2hex(substr($this->bytes, 10)); + return new Hexadecimal(bin2hex(substr($this->bytes, 10))); } - public function getTimeHiAndVersion(): string + public function getTimeHiAndVersion(): Hexadecimal { - return bin2hex(substr($this->bytes, 6, 2)); + return new Hexadecimal(bin2hex(substr($this->bytes, 6, 2))); } - public function getTimeLow(): string + public function getTimeLow(): Hexadecimal { - return bin2hex(substr($this->bytes, 0, 4)); + return new Hexadecimal(bin2hex(substr($this->bytes, 0, 4))); } - public function getTimeMid(): string + public function getTimeMid(): Hexadecimal { - return bin2hex(substr($this->bytes, 4, 2)); + return new Hexadecimal(bin2hex(substr($this->bytes, 4, 2))); } - public function getTimestamp(): string + public function getTimestamp(): Hexadecimal { - return sprintf( + return new Hexadecimal(sprintf( '%03x%04s%08s', - hexdec($this->getTimeHiAndVersion()) & 0x0fff, - $this->getTimeMid(), - $this->getTimeLow() - ); + hexdec($this->getTimeHiAndVersion()->toString()) & 0x0fff, + $this->getTimeMid()->toString(), + $this->getTimeLow()->toString() + )); } public function getVersion(): ?int diff --git a/src/Rfc4122/FieldsInterface.php b/src/Rfc4122/FieldsInterface.php index 782b6b9..24ef120 100644 --- a/src/Rfc4122/FieldsInterface.php +++ b/src/Rfc4122/FieldsInterface.php @@ -15,6 +15,7 @@ declare(strict_types=1); namespace Ramsey\Uuid\Rfc4122; use Ramsey\Uuid\Fields\FieldsInterface as BaseFieldsInterface; +use Ramsey\Uuid\Type\Hexadecimal; /** * RFC 4122 defines fields for a specific variant of UUID @@ -42,42 +43,42 @@ interface FieldsInterface extends BaseFieldsInterface * Returns the full 16-bit clock sequence, with the variant bits (two most * significant bits) masked out */ - public function getClockSeq(): string; + public function getClockSeq(): Hexadecimal; /** * Returns the high field of the clock sequence multiplexed with the variant */ - public function getClockSeqHiAndReserved(): string; + public function getClockSeqHiAndReserved(): Hexadecimal; /** * Returns the low field of the clock sequence */ - public function getClockSeqLow(): string; + public function getClockSeqLow(): Hexadecimal; /** * Returns the node field */ - public function getNode(): string; + public function getNode(): Hexadecimal; /** * Returns the high field of the timestamp multiplexed with the version */ - public function getTimeHiAndVersion(): string; + public function getTimeHiAndVersion(): Hexadecimal; /** * Returns the low field of the timestamp */ - public function getTimeLow(): string; + public function getTimeLow(): Hexadecimal; /** * Returns the middle field of the timestamp */ - public function getTimeMid(): string; + public function getTimeMid(): Hexadecimal; /** * Returns the full 60-bit timestamp, without the version */ - public function getTimestamp(): string; + public function getTimestamp(): Hexadecimal; /** * Returns the variant diff --git a/src/Uuid.php b/src/Uuid.php index 66c0964..be6a8de 100644 --- a/src/Uuid.php +++ b/src/Uuid.php @@ -22,8 +22,9 @@ use Ramsey\Uuid\Converter\TimeConverterInterface; use Ramsey\Uuid\Exception\DateTimeException; use Ramsey\Uuid\Exception\UnsatisfiedDependencyException; use Ramsey\Uuid\Exception\UnsupportedOperationException; +use Ramsey\Uuid\Fields\FieldsInterface; use Ramsey\Uuid\Rfc4122\Fields; -use Ramsey\Uuid\Rfc4122\FieldsInterface; +use Ramsey\Uuid\Rfc4122\FieldsInterface as Rfc4122FieldsInterface; /** * Represents a RFC 4122 universally unique identifier (UUID) @@ -156,7 +157,7 @@ class Uuid implements UuidInterface /** * The fields that make up this UUID * - * @var FieldsInterface + * @var Rfc4122FieldsInterface */ protected $fields; @@ -285,12 +286,12 @@ class Uuid implements UuidInterface */ public function getClockSeqHiAndReserved(): string { - return $this->numberConverter->fromHex($this->fields->getClockSeqHiAndReserved()); + return $this->numberConverter->fromHex($this->fields->getClockSeqHiAndReserved()->toString()); } public function getClockSeqHiAndReservedHex(): string { - return $this->fields->getClockSeqHiAndReserved(); + return $this->fields->getClockSeqHiAndReserved()->toString(); } /** @@ -298,12 +299,12 @@ class Uuid implements UuidInterface */ public function getClockSeqLow(): string { - return $this->numberConverter->fromHex($this->fields->getClockSeqLow()); + return $this->numberConverter->fromHex($this->fields->getClockSeqLow()->toString()); } public function getClockSeqLowHex(): string { - return $this->fields->getClockSeqLow(); + return $this->fields->getClockSeqLow()->toString(); } /** @@ -323,12 +324,12 @@ class Uuid implements UuidInterface */ public function getClockSequence(): string { - return $this->numberConverter->fromHex($this->fields->getClockSeq()); + return $this->numberConverter->fromHex($this->fields->getClockSeq()->toString()); } public function getClockSequenceHex(): string { - return $this->fields->getClockSeq(); + return $this->fields->getClockSeq()->toString(); } public function getNumberConverter(): NumberConverterInterface @@ -362,34 +363,11 @@ class Uuid implements UuidInterface } /** - * Returns an array of the fields of this UUID, with keys named according - * to the RFC 4122 names for the fields. - * - * * **time_low**: The low field of the timestamp, an unsigned 32-bit integer - * * **time_mid**: The middle field of the timestamp, an unsigned 16-bit integer - * * **time_hi_and_version**: The high field of the timestamp multiplexed with - * the version number, an unsigned 16-bit integer - * * **clock_seq_hi_and_reserved**: The high field of the clock sequence - * multiplexed with the variant, an unsigned 8-bit integer - * * **clock_seq_low**: The low field of the clock sequence, an unsigned - * 8-bit integer - * * **node**: The spatially unique node identifier, an unsigned 48-bit - * integer - * - * @link http://tools.ietf.org/html/rfc4122#section-4.1.2 RFC 4122, ยง 4.1.2: Layout and Byte Order - * - * @return string[] The UUID fields represented as integer values + * Returns the fields that comprise this UUID */ - public function getFields(): array + public function getFields(): FieldsInterface { - return [ - 'time_low' => $this->getTimeLow(), - 'time_mid' => $this->getTimeMid(), - 'time_hi_and_version' => $this->getTimeHiAndVersion(), - 'clock_seq_hi_and_reserved' => $this->getClockSeqHiAndReserved(), - 'clock_seq_low' => $this->getClockSeqLow(), - 'node' => $this->getNode(), - ]; + return $this->fields; } /** @@ -398,12 +376,12 @@ class Uuid implements UuidInterface public function getFieldsHex(): array { return [ - 'time_low' => $this->fields->getTimeLow(), - 'time_mid' => $this->fields->getTimeMid(), - 'time_hi_and_version' => $this->fields->getTimeHiAndVersion(), - 'clock_seq_hi_and_reserved' => $this->fields->getClockSeqHiAndReserved(), - 'clock_seq_low' => $this->fields->getClockSeqLow(), - 'node' => $this->fields->getNode(), + 'time_low' => $this->fields->getTimeLow()->toString(), + 'time_mid' => $this->fields->getTimeMid()->toString(), + 'time_hi_and_version' => $this->fields->getTimeHiAndVersion()->toString(), + 'clock_seq_hi_and_reserved' => $this->fields->getClockSeqHiAndReserved()->toString(), + 'clock_seq_low' => $this->fields->getClockSeqLow()->toString(), + 'node' => $this->fields->getNode()->toString(), ]; } @@ -429,9 +407,9 @@ class Uuid implements UuidInterface { return sprintf( '%02s%02s%012s', - $this->fields->getClockSeqHiAndReserved(), - $this->fields->getClockSeqLow(), - $this->fields->getNode() + $this->fields->getClockSeqHiAndReserved()->toString(), + $this->fields->getClockSeqLow()->toString(), + $this->fields->getNode()->toString() ); } @@ -447,9 +425,9 @@ class Uuid implements UuidInterface { return sprintf( '%08s%04s%04s', - $this->fields->getTimeLow(), - $this->fields->getTimeMid(), - $this->fields->getTimeHiAndVersion() + $this->fields->getTimeLow()->toString(), + $this->fields->getTimeMid()->toString(), + $this->fields->getTimeHiAndVersion()->toString() ); } @@ -482,12 +460,12 @@ class Uuid implements UuidInterface */ public function getNode(): string { - return $this->numberConverter->fromHex($this->fields->getNode()); + return $this->numberConverter->fromHex($this->fields->getNode()->toString()); } public function getNodeHex(): string { - return $this->fields->getNode(); + return $this->fields->getNode()->toString(); } /** @@ -495,12 +473,12 @@ class Uuid implements UuidInterface */ public function getTimeHiAndVersion(): string { - return $this->numberConverter->fromHex($this->fields->getTimeHiAndVersion()); + return $this->numberConverter->fromHex($this->fields->getTimeHiAndVersion()->toString()); } public function getTimeHiAndVersionHex(): string { - return $this->fields->getTimeHiAndVersion(); + return $this->fields->getTimeHiAndVersion()->toString(); } /** @@ -508,12 +486,12 @@ class Uuid implements UuidInterface */ public function getTimeLow(): string { - return $this->numberConverter->fromHex($this->fields->getTimeLow()); + return $this->numberConverter->fromHex($this->fields->getTimeLow()->toString()); } public function getTimeLowHex(): string { - return $this->fields->getTimeLow(); + return $this->fields->getTimeLow()->toString(); } /** @@ -521,12 +499,12 @@ class Uuid implements UuidInterface */ public function getTimeMid(): string { - return $this->numberConverter->fromHex($this->fields->getTimeMid()); + return $this->numberConverter->fromHex($this->fields->getTimeMid()->toString()); } public function getTimeMidHex(): string { - return $this->fields->getTimeMid(); + return $this->fields->getTimeMid()->toString(); } /** @@ -551,7 +529,7 @@ class Uuid implements UuidInterface throw new UnsupportedOperationException('Not a time-based UUID'); } - return $this->numberConverter->fromHex($this->fields->getTimestamp()); + return $this->numberConverter->fromHex($this->fields->getTimestamp()->toString()); } public function getTimestampHex(): string @@ -560,7 +538,7 @@ class Uuid implements UuidInterface throw new UnsupportedOperationException('Not a time-based UUID'); } - return $this->fields->getTimestamp(); + return $this->fields->getTimestamp()->toString(); } public function getUrn(): string diff --git a/src/UuidInterface.php b/src/UuidInterface.php index 1fcd068..26b9710 100644 --- a/src/UuidInterface.php +++ b/src/UuidInterface.php @@ -17,6 +17,7 @@ namespace Ramsey\Uuid; use DateTimeInterface; use JsonSerializable; use Ramsey\Uuid\Converter\NumberConverterInterface; +use Ramsey\Uuid\Fields\FieldsInterface; use Serializable; /** @@ -62,6 +63,11 @@ interface UuidInterface extends JsonSerializable, Serializable */ public function getBytes(): string; + /** + * Returns the fields that comprise this UUID + */ + public function getFields(): FieldsInterface; + /** * Returns the number converter to use when converting hex values to/from integers */ diff --git a/tests/Guid/FieldsTest.php b/tests/Guid/FieldsTest.php index 1618cf7..0e68215 100644 --- a/tests/Guid/FieldsTest.php +++ b/tests/Guid/FieldsTest.php @@ -7,6 +7,7 @@ namespace Ramsey\Uuid\Test\Guid; use Ramsey\Uuid\Exception\InvalidArgumentException; use Ramsey\Uuid\Guid\Fields; use Ramsey\Uuid\Test\TestCase; +use Ramsey\Uuid\Type\Hexadecimal; class FieldsTest extends TestCase { @@ -102,7 +103,13 @@ class FieldsTest extends TestCase $bytes = (string) hex2bin($bytes); $fields = new Fields($bytes); - $this->assertSame($expectedValue, $fields->$methodName()); + $result = $fields->$methodName(); + + if ($result instanceof Hexadecimal) { + $this->assertSame($expectedValue, $result->toString()); + } else { + $this->assertSame($expectedValue, $result); + } } /** diff --git a/tests/Nonstandard/FieldsTest.php b/tests/Nonstandard/FieldsTest.php index 72347f1..6523177 100644 --- a/tests/Nonstandard/FieldsTest.php +++ b/tests/Nonstandard/FieldsTest.php @@ -7,6 +7,7 @@ namespace Ramsey\Uuid\Test\Nonstandard; use Ramsey\Uuid\Exception\InvalidArgumentException; use Ramsey\Uuid\Nonstandard\Fields; use Ramsey\Uuid\Test\TestCase; +use Ramsey\Uuid\Type\Hexadecimal; use Ramsey\Uuid\Uuid; class FieldsTest extends TestCase @@ -32,7 +33,13 @@ class FieldsTest extends TestCase $bytes = (string) hex2bin(str_replace('-', '', $uuid)); $fields = new Fields($bytes); - $this->assertSame($expectedValue, $fields->$methodName()); + $result = $fields->$methodName(); + + if ($result instanceof Hexadecimal) { + $this->assertSame($expectedValue, $result->toString()); + } else { + $this->assertSame($expectedValue, $result); + } } /** diff --git a/tests/Rfc4122/FieldsTest.php b/tests/Rfc4122/FieldsTest.php index 119e512..a79ee8a 100644 --- a/tests/Rfc4122/FieldsTest.php +++ b/tests/Rfc4122/FieldsTest.php @@ -7,6 +7,7 @@ namespace Ramsey\Uuid\Test\Rfc4122; use Ramsey\Uuid\Exception\InvalidArgumentException; use Ramsey\Uuid\Rfc4122\Fields; use Ramsey\Uuid\Test\TestCase; +use Ramsey\Uuid\Type\Hexadecimal; class FieldsTest extends TestCase { @@ -96,7 +97,13 @@ class FieldsTest extends TestCase $bytes = (string) hex2bin(str_replace('-', '', $uuid)); $fields = new Fields($bytes); - $this->assertSame($expectedValue, $fields->$methodName()); + $result = $fields->$methodName(); + + if ($result instanceof Hexadecimal) { + $this->assertSame($expectedValue, $result->toString()); + } else { + $this->assertSame($expectedValue, $result); + } } /** diff --git a/tests/UuidTest.php b/tests/UuidTest.php index 2fa6936..594e9f1 100644 --- a/tests/UuidTest.php +++ b/tests/UuidTest.php @@ -25,6 +25,7 @@ use Ramsey\Uuid\Generator\RandomGeneratorFactory; use Ramsey\Uuid\Generator\RandomGeneratorInterface; use Ramsey\Uuid\Guid\Guid; use Ramsey\Uuid\Provider\Time\FixedTimeProvider; +use Ramsey\Uuid\Rfc4122\FieldsInterface; use Ramsey\Uuid\Type\Time; use Ramsey\Uuid\Uuid; use Ramsey\Uuid\UuidFactory; @@ -185,19 +186,10 @@ class UuidTest extends TestCase public function testGetFields(): void { - $fields = [ - 'time_low' => '4285500592', - 'time_mid' => '50557', - 'time_hi_and_version' => '4577', - 'clock_seq_hi_and_reserved' => '155', - 'clock_seq_low' => '33', - 'node' => '8796630719078', - ]; - /** @var Uuid $uuid */ $uuid = Uuid::fromString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66'); - $this->assertSame($fields, $uuid->getFields()); + $this->assertInstanceOf(FieldsInterface::class, $uuid->getFields()); } public function testGetFieldsHex(): void