Skip to content

Commit

Permalink
private class constants
Browse files Browse the repository at this point in the history
readonly classes and properties
typed properties
  • Loading branch information
1ma committed Sep 24, 2023
1 parent b6dec76 commit 3d91b44
Show file tree
Hide file tree
Showing 8 changed files with 48 additions and 79 deletions.
59 changes: 26 additions & 33 deletions src/CombGenerator.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,10 @@
/**
* @see http://www.informit.com/articles/article.aspx?p=25862
*/
class CombGenerator implements UuidGenerator
final readonly class CombGenerator implements UuidGenerator
{
/**
* @var int
*/
private $exponent;

/**
* @var Version4Generator
*/
private $v4;
private int $exponent;
private Version4Generator $v4;

/**
* @param int $granularity Precision of the timestamps, ranging from second up to microsecond.
Expand All @@ -39,7 +32,7 @@ public function __construct(int $granularity = 6)
*/
public function generate(string $name = null): Uuid
{
$head = $this->procrust($this->timestamp());
$head = self::procrust($this->timestamp());
$tail = \substr($this->v4->generate()->asBytes(), -10);

return Uuid::fromBytes($head . $tail);
Expand All @@ -61,28 +54,6 @@ public function getOverflowDate(): \DateTimeImmutable
return new \DateTimeImmutable("@$maxTimestamp UTC");
}

/**
* Returns $timestamp "procrusted" to 6 bytes.
*
* If the timestamp is smaller than 6 bytes, leading 0 bits are appended.
* If the timestamp is larger than 6 bytes, its least significant bits are chopped off.
*
* The returned string is raw binary (each character encodes 8 bits)
* and has always the same size -- 6 bytes.
*
* @example '59b7d71f' => 0x000059b7d71f
* @example '3812e6738' => 0x0003812e6738
* @example '230bd00838' => 0x00230bd00838
* @example '15e76205236' => 0x015e76205236
* @example 'db09d433621' => 0x0db09d433621
* @example '88e624a01d4c' => 0x88e624a01d4c
* @example '558fd6e4124fb' => 0x558fd6e4124f
*/
private function procrust(string $timestamp): string
{
return \pack('H12', \str_pad(\substr($timestamp, 0, 12), 12, '0', STR_PAD_LEFT));
}

/**
* Returns the current unix timestamp as a hex-encoded string (that is, each character
* encodes 4 bits) with variable precision, ranging from second to microsecond.
Expand All @@ -103,4 +74,26 @@ private function timestamp(): string
{
return \dechex((int)(\microtime(true) * $this->exponent));
}

/**
* Returns $timestamp "procrusted" to 6 bytes.
*
* If the timestamp is smaller than 6 bytes, leading 0 bits are appended.
* If the timestamp is larger than 6 bytes, its least significant bits are chopped off.
*
* The returned string is raw binary (each character encodes 8 bits)
* and has always the same size -- 6 bytes.
*
* @example '59b7d71f' => 0x000059b7d71f
* @example '3812e6738' => 0x0003812e6738
* @example '230bd00838' => 0x00230bd00838
* @example '15e76205236' => 0x015e76205236
* @example 'db09d433621' => 0x0db09d433621
* @example '88e624a01d4c' => 0x88e624a01d4c
* @example '558fd6e4124fb' => 0x558fd6e4124f
*/
private static function procrust(string $timestamp): string
{
return \pack('H12', \str_pad(\substr($timestamp, 0, 12), 12, '0', STR_PAD_LEFT));
}
}
13 changes: 3 additions & 10 deletions src/SequentialGenerator.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,10 @@
*
* Don't use this one in production.
*/
class SequentialGenerator implements UuidGenerator
final class SequentialGenerator implements UuidGenerator
{
/**
* @var int
*/
private $counter;

/**
* @var string
*/
private $head;
private int $counter;
private readonly string $head;

/**
* @example $mark = 15 and $start = 10 will generate:
Expand Down
10 changes: 4 additions & 6 deletions src/Uuid.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,28 +7,26 @@
/**
* Value object that encapsulates the 128 bits of an UUID.
*/
class Uuid
final readonly class Uuid
{
/**
* The 'Nil' UUID described in section 4.1.7 of RFC 4122.
*/
const NIL = '00000000-0000-0000-0000-000000000000';
private const NIL = '00000000-0000-0000-0000-000000000000';

/**
* The regular expression of what the value object considers to be a valid UUID in textual form.
*
* It does not try to enforce any particular version.
*/
const TEXTUAL_FORMAT = '/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i';
private const TEXTUAL_FORMAT = '/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i';

/**
* Textual representation of the UUID byte sequence.
*
* @example '96aaab69-7b76-4461-b008-cbb9cfcb6fdf'
*
* @var string
*/
private $uuid;
private string $uuid;

/**
* @throws \InvalidArgumentException If $text is not a valid Uuid in string format.
Expand Down
15 changes: 6 additions & 9 deletions src/Version1Generator.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
*
* @see https://tools.ietf.org/html/rfc4122#section-4.2
*/
class Version1Generator implements UuidGenerator
final readonly class Version1Generator implements UuidGenerator
{
/**
* This is the number of 100-nanosecond intervals elapsed from
Expand All @@ -23,19 +23,16 @@ class Version1Generator implements UuidGenerator
* var_dump($g->getTimestamp());
* var_dump($g->getTimestamp() * -10000000);
*/
const GREGORIAN_OFFSET = 122192928000000000;
private const GREGORIAN_OFFSET = 122192928000000000;

/**
* Regular expression for matching MAC addresses.
*
* @example 01:23:45:67:89:ab
*/
const MAC_ADDR_FORMAT = '/^[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}$/i';
private const MAC_ADDR_FORMAT = '/^[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}$/i';

/**
* @var string
*/
private $nodeID;
private string $nodeID;

/**
* @param string $nodeID A valid MAC address.
Expand All @@ -55,7 +52,7 @@ public function __construct(string $nodeID)

public function generate(string $name = null): Uuid
{
$t = $this->timestamp();
$t = self::timestamp();

$bytes = \pack(
'NnnnH12',
Expand All @@ -81,7 +78,7 @@ public function generate(string $name = null): Uuid
* $maxT = (int)((PHP_INT_MAX - self::GREGORIAN_OFFSET)/10000000);
* var_dump(new \DateTimeImmutable("@$maxT UTC"));
*/
private function timestamp(): int
private static function timestamp(): int
{
return self::GREGORIAN_OFFSET + (int)(10000000 * \microtime(true));
}
Expand Down
2 changes: 1 addition & 1 deletion src/Version4Generator.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
*
* @see https://tools.ietf.org/html/rfc4122#section-4.4
*/
class Version4Generator implements UuidGenerator
final readonly class Version4Generator implements UuidGenerator
{
/**
* @throws \Exception When PHP cannot gather enough entropy to
Expand Down
15 changes: 6 additions & 9 deletions src/Version5Generator.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,21 +10,18 @@
*
* @see https://tools.ietf.org/html/rfc4122#section-4.3
*/
class Version5Generator implements UuidGenerator
final readonly class Version5Generator implements UuidGenerator
{
/**
* These are a few well known Uuids listed in Appendix C
* of RFC 4122 to be used as namespace identifiers.
*/
const NS_DNS = '6ba7b810-9dad-11d1-80b4-00c04fd430c8';
const NS_URL = '6ba7b811-9dad-11d1-80b4-00c04fd430c8';
const NS_OID = '6ba7b812-9dad-11d1-80b4-00c04fd430c8';
const NS_X500 = '6ba7b814-9dad-11d1-80b4-00c04fd430c8';
public const NS_DNS = '6ba7b810-9dad-11d1-80b4-00c04fd430c8';
public const NS_URL = '6ba7b811-9dad-11d1-80b4-00c04fd430c8';
public const NS_OID = '6ba7b812-9dad-11d1-80b4-00c04fd430c8';
public const NS_X500 = '6ba7b814-9dad-11d1-80b4-00c04fd430c8';

/**
* @var string
*/
private $nsBytes;
private string $nsBytes;

public function __construct(Uuid $namespace)
{
Expand Down
11 changes: 1 addition & 10 deletions tests/SequentialGeneratorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,17 +43,8 @@ public function testCustomMarksAndStarts(): void
self::assertSame('00000000-0000-000a-0000-00000000000d', (string) $sut->generate());
}

public function testOverflows(): void
public function testOverflow(): void
{
$sut = new SequentialGenerator(0, PHP_INT_MAX);

// After reaching PHP_INT_MAX the internal counter does not overflow.
// Instead, it converts to a floating point number and the ticking stops.
self::assertSame('00000000-0000-0000-7fff-ffffffffffff', (string) $sut->generate());
self::assertSame('00000000-0000-0000-8000-000000000000', (string) $sut->generate());
self::assertSame('00000000-0000-0000-8000-000000000000', (string) $sut->generate());
self::assertSame('00000000-0000-0000-8000-000000000000', (string) $sut->generate());

$sut = new SequentialGenerator(0, -2);

self::assertSame('00000000-0000-0000-ffff-fffffffffffe', (string) $sut->generate());
Expand Down
2 changes: 1 addition & 1 deletion tests/UuidTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ class UuidTest extends TestCase
{
public function testNilFactory(): void
{
self::assertSame(Uuid::NIL, Uuid::nil()->asString());
self::assertSame('00000000-0000-0000-0000-000000000000', Uuid::nil()->asString());
}

public function testAlias(): void
Expand Down

0 comments on commit 3d91b44

Please sign in to comment.