Skip to content
This repository was archived by the owner on Dec 15, 2024. It is now read-only.

Commit 9b2b384

Browse files
committed
Updated for Swift 5
1 parent 9e8c422 commit 9b2b384

File tree

1 file changed

+126
-169
lines changed

1 file changed

+126
-169
lines changed

Sources/SwiftFoundation/UUID.swift

Lines changed: 126 additions & 169 deletions
Original file line numberDiff line numberDiff line change
@@ -6,200 +6,157 @@
66
// Copyright © 2015 PureSwift. All rights reserved.
77
//
88

9-
#if os(macOS) || os(iOS) || os(watchOS) || os(tvOS)
10-
import Darwin
11-
import Foundation
12-
#elseif os(Linux)
13-
import Glibc
14-
import CUUID
15-
#endif
16-
17-
// MARK: - Linux
18-
19-
#if os(Linux) || XcodeLinux
9+
/// A representation of a universally unique identifier (```UUID```).
10+
public struct UUID {
2011

21-
/// A representation of a universally unique identifier (```UUID```).
22-
public struct UUID: ByteValue, Equatable, Hashable, RawRepresentable, CustomStringConvertible {
23-
24-
// MARK: - Static Properties
25-
26-
public static let length = 16
27-
public static let stringLength = 36
28-
public static let unformattedStringLength = 32
29-
30-
// MARK: - Properties
31-
32-
public var bytes: uuid_t
33-
34-
// MARK: - Initialization
35-
36-
/// Create a new UUID with RFC 4122 version 4 random bytes
37-
public init() {
38-
39-
var uuid = uuid_t(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)
40-
41-
withUnsafeMutablePointer(to: &uuid, { (valuePointer: UnsafeMutablePointer<uuid_t>) in
42-
43-
uuid_generate(unsafeBitCast(valuePointer, to: UnsafeMutablePointer<UInt8>.self))
44-
})
45-
46-
self.bytes = uuid
47-
}
48-
49-
/// Initializes a UUID with the specified bytes.
50-
public init(bytes: uuid_t) {
51-
52-
self.bytes = bytes
53-
}
54-
}
12+
// MARK: - Properties
5513

56-
// MARK: - RawRepresentable
14+
public let uuid: uuid_t
5715

58-
public extension UUID {
59-
60-
init?(rawValue: String) {
61-
62-
let uuidPointer = UnsafeMutablePointer<uuid_t>.allocate(capacity: 1)
63-
64-
defer { uuidPointer.deallocate(capacity: 1) }
65-
66-
guard uuid_parse(rawValue, unsafeBitCast(uuidPointer, to: UnsafeMutablePointer<UInt8>.self)) != -1
67-
else { return nil }
68-
69-
self.bytes = uuidPointer.pointee
70-
}
16+
// MARK: - Initialization
17+
18+
/// Create a new UUID with RFC 4122 version 4 random bytes
19+
public init() {
7120

72-
var rawValue: String {
73-
74-
var uuidCopy = bytes
75-
76-
var uuidString = POSIXUUIDStringType(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)
77-
78-
// withUnsafeMutablePointer(&uuidCopy, &uuidString) { (uuidPointer: UnsafeMutablePointer<uuid_t>, uuidStringPointer: UnsafeMutablePointer<POSIXUUIDStringType>) -> Void in
79-
80-
withUnsafeMutablePointer(to: &uuidCopy) { (uuidPointer: UnsafeMutablePointer<uuid_t>) in
81-
82-
withUnsafeMutablePointer(to: &uuidString) { (uuidStringPointer: UnsafeMutablePointer<POSIXUUIDStringType>) in
83-
84-
let stringBuffer = unsafeBitCast(uuidStringPointer, to: UnsafeMutablePointer<Int8>.self)
85-
86-
let uuidBuffer = unsafeBitCast(uuidPointer, to: UnsafeMutablePointer<UInt8>.self)
87-
88-
uuid_unparse(unsafeBitCast(uuidBuffer, to: UnsafePointer<UInt8>.self), stringBuffer)
89-
}
90-
}
91-
92-
return withUnsafeMutablePointer(to: &uuidString, { (valuePointer: UnsafeMutablePointer<POSIXUUIDStringType>) -> String in
93-
94-
let buffer = unsafeBitCast(valuePointer, to: UnsafeMutablePointer<CChar>.self)
95-
96-
return String(validatingUTF8: unsafeBitCast(buffer, to: UnsafePointer<CChar>.self))!
97-
})
98-
}
21+
let uuid = uuid_t(.random,.random,.random,.random,.random,.random,.random,.random,.random,.random,.random,.random,.random,.random,.random,.random)
22+
self.init(uuid: uuid)
9923
}
10024

101-
// MARK: - Hashable
102-
103-
public extension UUID {
104-
105-
var hashValue: Int {
106-
107-
return toData().hashValue
108-
}
25+
/// Create a UUID from a `uuid_t`.
26+
public init(uuid: uuid_t) {
27+
self.uuid = uuid
10928
}
11029

111-
// MARK: - Equatable
30+
// MARK: - UUID String
11231

113-
public func == (lhs: UUID, rhs: UUID) -> Bool {
114-
115-
return lhs.bytes.0 == rhs.bytes.0 &&
116-
lhs.bytes.1 == rhs.bytes.1 &&
117-
lhs.bytes.2 == rhs.bytes.2 &&
118-
lhs.bytes.3 == rhs.bytes.3 &&
119-
lhs.bytes.4 == rhs.bytes.4 &&
120-
lhs.bytes.5 == rhs.bytes.5 &&
121-
lhs.bytes.6 == rhs.bytes.6 &&
122-
lhs.bytes.7 == rhs.bytes.7 &&
123-
lhs.bytes.8 == rhs.bytes.8 &&
124-
lhs.bytes.9 == rhs.bytes.9 &&
125-
lhs.bytes.10 == rhs.bytes.10 &&
126-
lhs.bytes.11 == rhs.bytes.11 &&
127-
lhs.bytes.12 == rhs.bytes.12 &&
128-
lhs.bytes.13 == rhs.bytes.13 &&
129-
lhs.bytes.14 == rhs.bytes.14 &&
130-
lhs.bytes.15 == rhs.bytes.15
32+
/// Create a UUID from a string such as "E621E1F8-C36C-495A-93FC-0C247A3E6E5F".
33+
///
34+
/// Returns nil for invalid strings.
35+
public init?(uuidString string: String) {
36+
guard string.count == UUID.stringLength
37+
else { return nil }
38+
let components = string
39+
.split(separator: "-")
40+
guard components[0].count == 8,
41+
components[1].count == 4,
42+
components[2].count == 4,
43+
components[3].count == 4,
44+
components[4].count == 12
45+
else { return nil }
46+
let hexString = components
47+
.reduce("") { $0 + $1 }
48+
assert(hexString.count == UUID.length * 2)
49+
guard let bytes = [UInt8](hexadecimal: hexString)
50+
else { return nil }
51+
assert(bytes.count == UUID.length)
52+
self.init(uuid: uuid_t(bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7], bytes[8], bytes[9], bytes[10], bytes[11], bytes[12], bytes[13], bytes[14], bytes[15]))
53+
}
54+
55+
/// Returns a string created from the UUID, such as "E621E1F8-C36C-495A-93FC-0C247A3E6E5F"
56+
public var uuidString: String {
57+
return uuid.0.toHexadecimal()
58+
+ uuid.1.toHexadecimal()
59+
+ uuid.2.toHexadecimal()
60+
+ uuid.3.toHexadecimal()
61+
+ "-"
62+
+ uuid.4.toHexadecimal()
63+
+ uuid.5.toHexadecimal()
64+
+ "-"
65+
+ uuid.6.toHexadecimal()
66+
+ uuid.7.toHexadecimal()
67+
+ "-"
68+
+ uuid.8.toHexadecimal()
69+
+ uuid.9.toHexadecimal()
70+
+ "-"
71+
+ uuid.10.toHexadecimal()
72+
+ uuid.11.toHexadecimal()
73+
+ uuid.12.toHexadecimal()
74+
+ uuid.13.toHexadecimal()
75+
+ uuid.14.toHexadecimal()
76+
+ uuid.15.toHexadecimal()
13177
}
78+
}
13279

133-
#endif
80+
internal extension SwiftFoundation.UUID {
81+
82+
static var length: Int { return 16 }
83+
static var stringLength: Int { return 36 }
84+
}
13485

135-
// MARK: - Darwin
86+
// MARK: - Equatable
13687

137-
#if (os(macOS) || os(iOS) || os(watchOS) || os(tvOS)) && !XcodeLinux
88+
extension SwiftFoundation.UUID: Equatable {
13889

139-
public typealias UUID = Foundation.UUID
140-
141-
extension Foundation.UUID {
142-
143-
public static var length: Int { return 16 }
144-
public static var stringLength: Int { return 36 }
145-
public static var unformattedStringLength: Int { return 32 }
90+
public static func == (lhs: SwiftFoundation.UUID, rhs: SwiftFoundation.UUID) -> Bool {
91+
return lhs.uuid.0 == rhs.uuid.0 &&
92+
lhs.uuid.1 == rhs.uuid.1 &&
93+
lhs.uuid.2 == rhs.uuid.2 &&
94+
lhs.uuid.3 == rhs.uuid.3 &&
95+
lhs.uuid.4 == rhs.uuid.4 &&
96+
lhs.uuid.5 == rhs.uuid.5 &&
97+
lhs.uuid.6 == rhs.uuid.6 &&
98+
lhs.uuid.7 == rhs.uuid.7 &&
99+
lhs.uuid.8 == rhs.uuid.8 &&
100+
lhs.uuid.9 == rhs.uuid.9 &&
101+
lhs.uuid.10 == rhs.uuid.10 &&
102+
lhs.uuid.11 == rhs.uuid.11 &&
103+
lhs.uuid.12 == rhs.uuid.12 &&
104+
lhs.uuid.13 == rhs.uuid.13 &&
105+
lhs.uuid.14 == rhs.uuid.14 &&
106+
lhs.uuid.15 == rhs.uuid.15
146107
}
108+
}
109+
110+
// MARK: - Hashable
111+
112+
extension UUID: Hashable {
147113

148-
extension Foundation.UUID: ByteValue {
149-
150-
@inline(__always)
151-
public init(bytes: uuid_t) {
152-
153-
self.init(uuid: bytes)
154-
}
155-
156-
public var bytes: uuid_t {
157-
158-
@inline(__always)
159-
get { return uuid }
160-
161-
@inline(__always)
162-
set { self = Foundation.UUID(uuid: newValue) }
163-
}
114+
public func hash(into hasher: inout Hasher) {
115+
withUnsafeBytes(of: uuid) { hasher.combine(bytes: $0) }
164116
}
117+
}
118+
119+
// MARK: - CustomStringConvertible
120+
121+
extension UUID: CustomStringConvertible {
165122

166-
extension Foundation.UUID: RawRepresentable {
167-
168-
@inline(__always)
169-
public init?(rawValue uuidString: String) {
170-
171-
self.init(uuidString: uuidString)
172-
}
173-
174-
public var rawValue: String {
175-
176-
return uuidString
177-
}
123+
public var description: String {
124+
return uuidString
178125
}
179-
180-
#endif
126+
}
181127

182-
// MARK: - DataConvertible
128+
// MARK: - CustomReflectable
183129

184-
extension UUID: DataConvertible {
185-
186-
public init?(data: Data) {
187-
188-
guard data.count == UUID.length else { return nil }
130+
extension UUID: CustomReflectable {
131+
public var customMirror: Mirror {
132+
let c : [(label: String?, value: Any)] = []
133+
let m = Mirror(self, children:c, displayStyle: .struct)
134+
return m
135+
}
136+
}
137+
138+
// MARK: - Codable
139+
140+
extension UUID: Codable {
141+
public init(from decoder: Decoder) throws {
142+
let container = try decoder.singleValueContainer()
143+
let uuidString = try container.decode(String.self)
144+
145+
guard let uuid = UUID(uuidString: uuidString) else {
146+
throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: decoder.codingPath,
147+
debugDescription: "Attempted to decode UUID from invalid UUID string."))
148+
}
189149

190-
self.init(bytes: (data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7], data[8], data[9], data[10], data[11], data[12], data[13], data[14], data[15]))
150+
self = uuid
191151
}
192152

193-
public func toData() -> Data {
194-
195-
return Data(bytes: [bytes.0, bytes.1, bytes.2, bytes.3, bytes.4, bytes.5, bytes.6, bytes.7, bytes.8, bytes.9, bytes.10, bytes.11, bytes.12, bytes.13, bytes.14, bytes.15])
153+
public func encode(to encoder: Encoder) throws {
154+
var container = encoder.singleValueContainer()
155+
try container.encode(self.uuidString)
196156
}
197157
}
198158

199-
// MARK: - Private
159+
// MARK: - Supporting Types
200160

201-
#if os(macOS) || os(iOS) || os(watchOS) || os(tvOS)
202-
private typealias POSIXUUIDStringType = uuid_string_t
203-
#elseif os(Linux)
204-
private typealias POSIXUUIDStringType = (Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8)
205-
#endif
161+
public typealias uuid_t = (UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8)
162+
public typealias uuid_string_t = (Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8)

0 commit comments

Comments
 (0)