From 061512b3f90b586fa4feb18662b7e40934cdf985 Mon Sep 17 00:00:00 2001 From: Jevon Mao Date: Mon, 19 May 2025 18:47:31 -0700 Subject: [PATCH 1/3] Impelment LossLessStringConvertible for UUID --- Sources/FoundationEssentials/UUID.swift | 7 ++++++- Tests/FoundationEssentialsTests/UUIDTests.swift | 15 +++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/Sources/FoundationEssentials/UUID.swift b/Sources/FoundationEssentials/UUID.swift index 23b69a115..da3b5a7b0 100644 --- a/Sources/FoundationEssentials/UUID.swift +++ b/Sources/FoundationEssentials/UUID.swift @@ -16,7 +16,7 @@ public typealias uuid_string_t = (Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8 /// Represents UUID strings, which can be used to uniquely identify types, interfaces, and other items. @available(macOS 10.8, iOS 6.0, tvOS 9.0, watchOS 2.0, *) -public struct UUID : Hashable, Equatable, CustomStringConvertible, Sendable { +public struct UUID : Hashable, Equatable, CustomStringConvertible, Sendable, LosslessStringConvertible { public private(set) var uuid: uuid_t = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) /* Create a new UUID with RFC 4122 version 4 random bytes */ @@ -57,6 +57,11 @@ public struct UUID : Hashable, Equatable, CustomStringConvertible, Sendable { public init(uuid: uuid_t) { self.uuid = uuid } + + /// LosslessStringConvertible initializer + public init?(_ description: String) { + self.init(uuidString: description) + } /// Returns a string created from the UUID, such as "E621E1F8-C36C-495A-93FC-0C247A3E6E5F" public var uuidString: String { diff --git a/Tests/FoundationEssentialsTests/UUIDTests.swift b/Tests/FoundationEssentialsTests/UUIDTests.swift index a21707f55..9a01f4801 100644 --- a/Tests/FoundationEssentialsTests/UUIDTests.swift +++ b/Tests/FoundationEssentialsTests/UUIDTests.swift @@ -115,4 +115,19 @@ final class UUIDTests : XCTestCase { XCTAssertFalse(uuid2 > uuid1) XCTAssertTrue(uuid2 == uuid1) } + + func test_UUIDLosslessStringConvertible() { + let originalString = "E621E1F8-C36C-495A-93FC-0C247A3E6E5F" + let uuidFromString = UUID(originalString) + XCTAssertNotNil(uuidFromString, "UUID must be constructible from valid UUID string via LosslessStringConvertible") + XCTAssertEqual(uuidFromString?.description, originalString, "Round-tripped description must match original UUID string") + + let uuid = UUID(uuidString: originalString)! + XCTAssertEqual(uuid, UUID(uuid.description), "UUID must round-trip through LosslessStringConvertible") + + let invalidString = "not-a-uuid" + let invalidUUID = UUID(invalidString) + XCTAssertNil(invalidUUID, "Invalid UUID strings must result in nil from LosslessStringConvertible initializer") + } + } From fef8d59651e8e0f2d3efc2b95a138cf17cf8a670 Mon Sep 17 00:00:00 2001 From: Jevon Mao Date: Fri, 23 May 2025 22:14:34 -0700 Subject: [PATCH 2/3] Add availability annotation --- Sources/FoundationEssentials/UUID.swift | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Sources/FoundationEssentials/UUID.swift b/Sources/FoundationEssentials/UUID.swift index da3b5a7b0..9635956a2 100644 --- a/Sources/FoundationEssentials/UUID.swift +++ b/Sources/FoundationEssentials/UUID.swift @@ -58,7 +58,8 @@ public struct UUID : Hashable, Equatable, CustomStringConvertible, Sendable, Los self.uuid = uuid } - /// LosslessStringConvertible initializer + /// Create a UUID from a string representation conforming to `LosslessStringConvertible`. + @available(macOS 10.8, iOS 6.0, tvOS 9.0, watchOS 2.0, *) public init?(_ description: String) { self.init(uuidString: description) } From 9fae1cb8d63032159cd78f14162a35efa2ca728a Mon Sep 17 00:00:00 2001 From: Jevon Mao Date: Sat, 24 May 2025 17:19:46 -0700 Subject: [PATCH 3/3] Add foundationpreview 6.2 --- Sources/FoundationEssentials/UUID.swift | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/Sources/FoundationEssentials/UUID.swift b/Sources/FoundationEssentials/UUID.swift index 9635956a2..fa9cbbf62 100644 --- a/Sources/FoundationEssentials/UUID.swift +++ b/Sources/FoundationEssentials/UUID.swift @@ -16,7 +16,7 @@ public typealias uuid_string_t = (Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8 /// Represents UUID strings, which can be used to uniquely identify types, interfaces, and other items. @available(macOS 10.8, iOS 6.0, tvOS 9.0, watchOS 2.0, *) -public struct UUID : Hashable, Equatable, CustomStringConvertible, Sendable, LosslessStringConvertible { +public struct UUID : Hashable, Equatable, CustomStringConvertible, Sendable { public private(set) var uuid: uuid_t = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) /* Create a new UUID with RFC 4122 version 4 random bytes */ @@ -58,12 +58,6 @@ public struct UUID : Hashable, Equatable, CustomStringConvertible, Sendable, Los self.uuid = uuid } - /// Create a UUID from a string representation conforming to `LosslessStringConvertible`. - @available(macOS 10.8, iOS 6.0, tvOS 9.0, watchOS 2.0, *) - public init?(_ description: String) { - self.init(uuidString: description) - } - /// Returns a string created from the UUID, such as "E621E1F8-C36C-495A-93FC-0C247A3E6E5F" public var uuidString: String { var bytes: uuid_string_t = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) @@ -156,3 +150,11 @@ extension UUID : Comparable { return result < 0 } } + +@available(FoundationPreview 6.2, *) +extension UUID: LosslessStringConvertible { + /// Create a UUID from a string representation conforming to `LosslessStringConvertible`. + public init?(_ description: String) { + self.init(uuidString: description) + } +}