feat: support max UUIDs

This commit is contained in:
Ben Ramsey
2022-09-14 20:44:24 -05:00
parent e6164bd687
commit 685c2f3f23
18 changed files with 247 additions and 17 deletions
+11 -3
View File
@@ -17,6 +17,7 @@ namespace Ramsey\Uuid\Guid;
use Ramsey\Uuid\Exception\InvalidArgumentException;
use Ramsey\Uuid\Fields\SerializableFieldsTrait;
use Ramsey\Uuid\Rfc4122\FieldsInterface;
use Ramsey\Uuid\Rfc4122\MaxTrait;
use Ramsey\Uuid\Rfc4122\NilTrait;
use Ramsey\Uuid\Rfc4122\VariantTrait;
use Ramsey\Uuid\Rfc4122\VersionTrait;
@@ -44,6 +45,7 @@ use const STR_PAD_LEFT;
*/
final class Fields implements FieldsInterface
{
use MaxTrait;
use NilTrait;
use SerializableFieldsTrait;
use VariantTrait;
@@ -149,7 +151,13 @@ final class Fields implements FieldsInterface
public function getClockSeq(): Hexadecimal
{
$clockSeq = hexdec(bin2hex(substr($this->bytes, 8, 2))) & 0x3fff;
if ($this->isMax()) {
$clockSeq = 0xffff;
} elseif ($this->isNil()) {
$clockSeq = 0x0000;
} else {
$clockSeq = hexdec(bin2hex(substr($this->bytes, 8, 2))) & 0x3fff;
}
return new Hexadecimal(str_pad(dechex($clockSeq), 4, '0', STR_PAD_LEFT));
}
@@ -171,7 +179,7 @@ final class Fields implements FieldsInterface
public function getVersion(): ?int
{
if ($this->isNil()) {
if ($this->isNil() || $this->isMax()) {
return null;
}
@@ -183,7 +191,7 @@ final class Fields implements FieldsInterface
private function isCorrectVariant(): bool
{
if ($this->isNil()) {
if ($this->isNil() || $this->isMax()) {
return true;
}
+5
View File
@@ -130,4 +130,9 @@ final class Fields implements FieldsInterface
{
return false;
}
public function isMax(): bool
{
return false;
}
}
+10 -3
View File
@@ -40,6 +40,7 @@ use const STR_PAD_LEFT;
*/
final class Fields implements FieldsInterface
{
use MaxTrait;
use NilTrait;
use SerializableFieldsTrait;
use VariantTrait;
@@ -88,7 +89,13 @@ final class Fields implements FieldsInterface
public function getClockSeq(): Hexadecimal
{
$clockSeq = hexdec(bin2hex(substr($this->bytes, 8, 2))) & 0x3fff;
if ($this->isMax()) {
$clockSeq = 0xffff;
} elseif ($this->isNil()) {
$clockSeq = 0x0000;
} else {
$clockSeq = hexdec(bin2hex(substr($this->bytes, 8, 2))) & 0x3fff;
}
return new Hexadecimal(str_pad(dechex($clockSeq), 4, '0', STR_PAD_LEFT));
}
@@ -184,7 +191,7 @@ final class Fields implements FieldsInterface
public function getVersion(): ?int
{
if ($this->isNil()) {
if ($this->isNil() || $this->isMax()) {
return null;
}
@@ -196,7 +203,7 @@ final class Fields implements FieldsInterface
private function isCorrectVariant(): bool
{
if ($this->isNil()) {
if ($this->isNil() || $this->isMax()) {
return true;
}
+41
View File
@@ -0,0 +1,41 @@
<?php
/**
* This file is part of the ramsey/uuid library
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>
* @license http://opensource.org/licenses/MIT MIT
*/
declare(strict_types=1);
namespace Ramsey\Uuid\Rfc4122;
/**
* Provides common functionality for max UUIDs
*
* The max UUID is special form of UUID that is specified to have all 128 bits
* set to one. It is the inverse of the nil UUID.
*
* @link https://datatracker.ietf.org/doc/html/draft-peabody-dispatch-new-uuid-format-04#section-5.4 Max UUID
*
* @psalm-immutable
*/
trait MaxTrait
{
/**
* Returns the bytes that comprise the fields
*/
abstract public function getBytes(): string;
/**
* Returns true if the byte string represents a max UUID
*/
public function isMax(): bool
{
return $this->getBytes() === "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff";
}
}
+27
View File
@@ -0,0 +1,27 @@
<?php
/**
* This file is part of the ramsey/uuid library
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>
* @license http://opensource.org/licenses/MIT MIT
*/
declare(strict_types=1);
namespace Ramsey\Uuid\Rfc4122;
use Ramsey\Uuid\Uuid;
/**
* The max UUID is special form of UUID that is specified to have all 128 bits
* set to one
*
* @psalm-immutable
*/
final class MaxUuid extends Uuid implements UuidInterface
{
}
+5
View File
@@ -73,12 +73,17 @@ class UuidBuilder implements UuidBuilderInterface
public function build(CodecInterface $codec, string $bytes): UuidInterface
{
try {
/** @var Fields $fields */
$fields = $this->buildFields($bytes);
if ($fields->isNil()) {
return new NilUuid($fields, $this->numberConverter, $codec, $this->timeConverter);
}
if ($fields->isMax()) {
return new MaxUuid($fields, $this->numberConverter, $codec, $this->timeConverter);
}
switch ($fields->getVersion()) {
case Uuid::UUID_TYPE_TIME:
return new UuidV1($fields, $this->numberConverter, $codec, $this->timeConverter);
+6
View File
@@ -58,6 +58,12 @@ trait VariantTrait
throw new InvalidBytesException('Invalid number of bytes');
}
if ($this->isMax() || $this->isNil()) {
// RFC 4122 defines these special types of UUID, so we will consider
// them as belonging to the RFC 4122 variant.
return Uuid::RFC_4122;
}
/** @var array $parts */
$parts = unpack('n*', $this->getBytes());
+6 -1
View File
@@ -28,6 +28,11 @@ trait VersionTrait
*/
abstract public function getVersion(): ?int;
/**
* Returns true if these fields represent a max UUID
*/
abstract public function isMax(): bool;
/**
* Returns true if these fields represent a nil UUID
*/
@@ -40,7 +45,7 @@ trait VersionTrait
*/
private function isCorrectVersion(): bool
{
if ($this->isNil()) {
if ($this->isNil() || $this->isMax()) {
return true;
}
+8
View File
@@ -84,6 +84,14 @@ class Uuid implements UuidInterface
*/
public const NIL = '00000000-0000-0000-0000-000000000000';
/**
* The max UUID is a special form of UUID that is specified to have all 128
* bits set to one
*
* @link https://datatracker.ietf.org/doc/html/draft-peabody-dispatch-new-uuid-format-04#section-5.4 Max UUID
*/
public const MAX = 'ffffffff-ffff-ffff-ffff-ffffffffffff';
/**
* Variant: reserved, NCS backward compatibility
*