diff --git a/docs/quickstart.rst b/docs/quickstart.rst index d1ee60d4..06bcf77c 100644 --- a/docs/quickstart.rst +++ b/docs/quickstart.rst @@ -100,6 +100,8 @@ library. - Checks whether a string is a valid UUID. * - :php:meth:`Uuid::fromString() ` - Creates a UUID instance from a string UUID. + * - :php:meth:`Uuid::fromStrictString() ` + - Creates a UUID from a valid string representation. * - :php:meth:`Uuid::fromBytes() ` - Creates a UUID instance from a 16-byte string. * - :php:meth:`Uuid::fromInteger() ` diff --git a/docs/reference/uuid.rst b/docs/reference/uuid.rst index c77ab11d..93245ad2 100644 --- a/docs/reference/uuid.rst +++ b/docs/reference/uuid.rst @@ -163,6 +163,14 @@ the ramsey/uuid library. :param string $uuid: The string standard representation of a UUID :returntype: Ramsey\\Uuid\\UuidInterface + .. php:staticmethod:: fromStrictString($uuid) + + Creates a UUID from a valid string representation, validated against + the isValid method. + + :param string $uuid: The string standard representation of a UUID + :returntype: Ramsey\\Uuid\\UuidInterface + .. php:staticmethod:: fromBytes($bytes) Creates an instance of UuidInterface from a 16-byte string. diff --git a/docs/reference/uuidfactoryinterface.rst b/docs/reference/uuidfactoryinterface.rst index c68a61de..e9c91a48 100644 --- a/docs/reference/uuidfactoryinterface.rst +++ b/docs/reference/uuidfactoryinterface.rst @@ -76,6 +76,14 @@ UuidFactoryInterface :param string $uuid: The string standard representation of a UUID :returntype: Ramsey\\Uuid\\UuidInterface + .. php:method:: fromStrictString($uuid) + + Creates a UUID from a valid string representation, validated against + the isValid method. + + :param string $uuid: The string standard representation of a UUID + :returntype: Ramsey\\Uuid\\UuidInterface + .. php:method:: fromBytes($bytes) Creates an instance of UuidInterface from a 16-byte string. diff --git a/src/Uuid.php b/src/Uuid.php index e0384a50..c3923110 100644 --- a/src/Uuid.php +++ b/src/Uuid.php @@ -19,6 +19,7 @@ use Ramsey\Uuid\Codec\CodecInterface; use Ramsey\Uuid\Converter\NumberConverterInterface; use Ramsey\Uuid\Converter\TimeConverterInterface; +use Ramsey\Uuid\Exception\InvalidUuidStringException; use Ramsey\Uuid\Exception\UnsupportedOperationException; use Ramsey\Uuid\Fields\FieldsInterface; use Ramsey\Uuid\Lazy\LazyUuidFromString; @@ -494,6 +495,28 @@ public static function fromString(string $uuid): UuidInterface return self::getFactory()->fromString($uuid); } + /** + * Creates a UUID from a valid string representation, validated against the isValid method + * + * @param string $uuid A valid UUID string representation + * + * @return UuidInterface A UuidInterface instance created from a valid UUID + * string representation + * + * @throws InvalidUuidStringException + * + * @psalm-pure note: changing the internal factory is an edge case not covered by purity invariants, + * but under constant factory setups, this method operates in functionally pure manners + */ + public static function fromStrictString(string $uuid): UuidInterface + { + if (! self::isValid($uuid)) { + throw new InvalidUuidStringException('Invalid UUID string: ' . $uuid); + } + + return self::fromString($uuid); + } + /** * Creates a UUID from a DateTimeInterface instance * diff --git a/src/UuidFactory.php b/src/UuidFactory.php index 1b06ea6e..26e0bcce 100644 --- a/src/UuidFactory.php +++ b/src/UuidFactory.php @@ -19,6 +19,7 @@ use Ramsey\Uuid\Codec\CodecInterface; use Ramsey\Uuid\Converter\NumberConverterInterface; use Ramsey\Uuid\Converter\TimeConverterInterface; +use Ramsey\Uuid\Exception\InvalidUuidStringException; use Ramsey\Uuid\Generator\DceSecurityGeneratorInterface; use Ramsey\Uuid\Generator\DefaultTimeGenerator; use Ramsey\Uuid\Generator\NameGeneratorInterface; @@ -279,6 +280,18 @@ public function fromString(string $uuid): UuidInterface return $this->codec->decode($uuid); } + /** + * @psalm-pure + */ + public function fromStrictString(string $uuid): UuidInterface + { + if (! $this->getValidator()->validate($uuid)) { + throw new InvalidUuidStringException('Invalid UUID string: ' . $uuid); + } + + return $this->codec->decode($uuid); + } + /** * @psalm-pure */ diff --git a/src/UuidFactoryInterface.php b/src/UuidFactoryInterface.php index d99fc9d5..c4065ff9 100644 --- a/src/UuidFactoryInterface.php +++ b/src/UuidFactoryInterface.php @@ -15,6 +15,7 @@ namespace Ramsey\Uuid; use DateTimeInterface; +use Ramsey\Uuid\Exception\InvalidUuidStringException; use Ramsey\Uuid\Type\Hexadecimal; use Ramsey\Uuid\Type\Integer as IntegerObject; use Ramsey\Uuid\Validator\ValidatorInterface; @@ -80,6 +81,20 @@ public function fromInteger(string $integer): UuidInterface; */ public function fromString(string $uuid): UuidInterface; + /** + * Creates a UUID from a valid string representation, validated against the isValid method + * + * @param string $uuid A valid UUID string representation + * + * @return UuidInterface A UuidInterface instance created from a valid UUID + * string representation + * + * @throws InvalidUuidStringException + * + * @psalm-pure + */ + public function fromStrictString(string $uuid): UuidInterface; + /** * Returns the validator to use for the factory * diff --git a/tests/UuidTest.php b/tests/UuidTest.php index feea5a04..15f115c8 100644 --- a/tests/UuidTest.php +++ b/tests/UuidTest.php @@ -73,6 +73,34 @@ public function testFromString(): void Uuid::fromString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66') ->toString() ); + + $this->assertSame( + '00000000-0000-0000-0000-000000000000', + Uuid::fromString('00000000000000000000000000000000') + ->toString() + ); + } + + public function testFromStrictString(): void + { + $this->assertSame( + 'ff6f8cb0-c57d-11e1-9b21-0800200c9a66', + Uuid::fromStrictString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66') + ->toString() + ); + + $this->assertSame( + '00000000-0000-0000-0000-000000000000', + Uuid::fromStrictString('00000000-0000-0000-0000-000000000000') + ->toString() + ); + } + + public function testFromStrictStringWithInvalidUuidString(): void + { + $this->expectException(InvalidUuidStringException::class); + + Uuid::fromStrictString('00000000000000000000000000000000'); } public function testFromHexadecimal(): void