@@ -11,172 +11,172 @@ import RFC_5321
1111
1212/// A domain name that can be represented according to different RFC standards
1313public struct _Domain : Hashable , Sendable {
14- let rfc1035 : RFC_1035 . Domain ?
15- let rfc1123 : RFC_1123 . Domain ?
16- let rfc5321 : RFC_5321 . Domain
17-
18- /// Initialize with a domain string
19- public init ( _ string: String ) throws {
20- // RFC 5321 is required as it's our most permissive format
21- self . rfc5321 = try RFC_5321 . Domain ( string)
22-
23- // Try to initialize stricter formats if possible
24- self . rfc1123 = try ? RFC_1123 . Domain ( string)
25- self . rfc1035 = try ? RFC_1035 . Domain ( string)
26- }
27-
28- /// Initialize with an array of labels
29- public init ( labels: [ String ] ) throws {
30- try self . init ( labels. joined ( separator: " . " ) )
31- }
14+ let rfc1035 : RFC_1035 . Domain ?
15+ let rfc1123 : RFC_1123 . Domain ?
16+ let rfc5321 : RFC_5321 . Domain
17+
18+ /// Initialize with a domain string
19+ public init ( _ string: String ) throws {
20+ // RFC 5321 is required as it's our most permissive format
21+ self . rfc5321 = try RFC_5321 . Domain ( string)
22+
23+ // Try to initialize stricter formats if possible
24+ self . rfc1123 = try ? RFC_1123 . Domain ( string)
25+ self . rfc1035 = try ? RFC_1035 . Domain ( string)
26+ }
27+
28+ /// Initialize with an array of labels
29+ public init ( labels: [ String ] ) throws {
30+ try self . init ( labels. joined ( separator: " . " ) )
31+ }
3232}
3333
3434public typealias Domain = _Domain
3535
3636extension Domain {
37- /// Initialize from RFC1035
38- public init ( rfc1035: RFC_1035 . Domain ) throws {
39- self . rfc1035 = rfc1035
40- self . rfc1123 = try {
41- guard let domain = try ? RFC_1123 . Domain ( rfc1035. name) else {
42- throw DomainError . conversionFailure
43- }
44- return domain
45- } ( )
46- self . rfc5321 = try {
47- guard let domain = try ? RFC_5321 . Domain ( rfc1035. name) else {
48- throw DomainError . conversionFailure
49- }
50- return domain
51- } ( )
52- }
53-
54- /// Initialize from RFC1123
55- public init ( rfc1123: RFC_1123 . Domain ) throws {
56- self . rfc1035 = nil // RFC1123 may not be RFC1035 compliant
57- self . rfc1123 = rfc1123
58- self . rfc5321 = try {
59- guard let domain = try ? RFC_5321 . Domain ( rfc1123. name) else {
60- throw DomainError . conversionFailure
61- }
62- return domain
63- } ( )
64- }
65-
66- /// Initialize from RFC_5321.Domain
67- public init ( rfc5321: RFC_5321 . Domain ) {
68- self . rfc1035 = nil // RFC_5321.Domain may not be RFC1035 compliant
69- self . rfc1123 = nil // RFC_5321.Domain may not be RFC1123 compliant
70- self . rfc5321 = rfc5321
71- }
37+ /// Initialize from RFC1035
38+ public init ( rfc1035: RFC_1035 . Domain ) throws {
39+ self . rfc1035 = rfc1035
40+ self . rfc1123 = try {
41+ guard let domain = try ? RFC_1123 . Domain ( rfc1035. name) else {
42+ throw DomainError . conversionFailure
43+ }
44+ return domain
45+ } ( )
46+ self . rfc5321 = try {
47+ guard let domain = try ? RFC_5321 . Domain ( rfc1035. name) else {
48+ throw DomainError . conversionFailure
49+ }
50+ return domain
51+ } ( )
52+ }
53+
54+ /// Initialize from RFC1123
55+ public init ( rfc1123: RFC_1123 . Domain ) throws {
56+ self . rfc1035 = nil // RFC1123 may not be RFC1035 compliant
57+ self . rfc1123 = rfc1123
58+ self . rfc5321 = try {
59+ guard let domain = try ? RFC_5321 . Domain ( rfc1123. name) else {
60+ throw DomainError . conversionFailure
61+ }
62+ return domain
63+ } ( )
64+ }
65+
66+ /// Initialize from RFC_5321.Domain
67+ public init ( rfc5321: RFC_5321 . Domain ) {
68+ self . rfc1035 = nil // RFC_5321.Domain may not be RFC1035 compliant
69+ self . rfc1123 = nil // RFC_5321.Domain may not be RFC1123 compliant
70+ self . rfc5321 = rfc5321
71+ }
7272}
7373
7474// MARK: - Properties
7575extension Domain {
76- /// The domain string, using the most specific format available
77- public var name : String {
78- rfc1035? . name ?? rfc1123? . name ?? rfc5321. name
79- }
80-
81- /// The top-level domain if available (only for RFC1035/1123 domains)
82- public var tld : String ? {
83- rfc1035? . tld? . stringValue ?? rfc1123? . tld? . stringValue
84- }
85-
86- /// The second-level domain if available (only for RFC1035/1123 domains)
87- public var sld : String ? {
88- rfc1035? . sld? . stringValue ?? rfc1123? . sld? . stringValue
89- }
90-
91- /// Returns true if this is a standard domain (not an IP address)
92- public var isStandardDomain : Bool {
93- rfc1123 != nil
94- }
95-
96- // /// Returns true if this is an IP address literal
97- // public var isAddressLiteral: Bool {
98- // rfc5321.isAddressLiteral
99- // }
100- }
76+ /// The domain string, using the most specific format available
77+ public var name : String {
78+ rfc1035? . name ?? rfc1123? . name ?? rfc5321. name
79+ }
10180
102- // MARK: - Domain Operations
103- extension Domain {
104- /// Returns true if this is a subdomain of the given domain
105- public func isSubdomain( of parent: Domain ) -> Bool {
106- // Use the most specific format available for both domains
107- if let myRFC1035 = rfc1035, let parentRFC1035 = parent. rfc1035 {
108- return myRFC1035. isSubdomain ( of: parentRFC1035)
81+ /// The top-level domain if available (only for RFC1035/1123 domains)
82+ public var tld : String ? {
83+ rfc1035? . tld? . stringValue ?? rfc1123? . tld? . stringValue
10984 }
110- if let myRFC1123 = rfc1123, let parentRFC1123 = parent. rfc1123 {
111- return myRFC1123. isSubdomain ( of: parentRFC1123)
85+
86+ /// The second-level domain if available (only for RFC1035/1123 domains)
87+ public var sld : String ? {
88+ rfc1035? . sld? . stringValue ?? rfc1123? . sld? . stringValue
11289 }
113- return false // Can't determine subdomain relationship for RFC_5321.Domain address literals
114- }
115-
116- /// Creates a subdomain by prepending new labels
117- public func addingSubdomain( _ components: String ... ) throws -> Domain {
118- // Use the most specific format available
119- if let domain = rfc1035 {
120- return try Domain ( rfc1035: domain. addingSubdomain ( components) )
90+
91+ /// Returns true if this is a standard domain (not an IP address)
92+ public var isStandardDomain : Bool {
93+ rfc1123 != nil
12194 }
122- if let domain = rfc1123 {
123- return try Domain ( rfc1123: domain. addingSubdomain ( components) )
95+
96+ // /// Returns true if this is an IP address literal
97+ // public var isAddressLiteral: Bool {
98+ // rfc5321.isAddressLiteral
99+ // }
100+ }
101+
102+ // MARK: - Domain Operations
103+ extension Domain {
104+ /// Returns true if this is a subdomain of the given domain
105+ public func isSubdomain( of parent: Domain ) -> Bool {
106+ // Use the most specific format available for both domains
107+ if let myRFC1035 = rfc1035, let parentRFC1035 = parent. rfc1035 {
108+ return myRFC1035. isSubdomain ( of: parentRFC1035)
109+ }
110+ if let myRFC1123 = rfc1123, let parentRFC1123 = parent. rfc1123 {
111+ return myRFC1123. isSubdomain ( of: parentRFC1123)
112+ }
113+ return false // Can't determine subdomain relationship for RFC_5321.Domain address literals
124114 }
125- throw DomainError . cannotCreateSubdomain
126- }
127-
128- /// Returns the parent domain by removing the leftmost label
129- public func parent( ) throws -> Domain ? {
130- // Use the most specific format available
131- if let domain = rfc1035, let parent = try domain. parent ( ) {
132- return try Domain ( rfc1035: parent)
115+
116+ /// Creates a subdomain by prepending new labels
117+ public func addingSubdomain( _ components: String ... ) throws -> Domain {
118+ // Use the most specific format available
119+ if let domain = rfc1035 {
120+ return try Domain ( rfc1035: domain. addingSubdomain ( components) )
121+ }
122+ if let domain = rfc1123 {
123+ return try Domain ( rfc1123: domain. addingSubdomain ( components) )
124+ }
125+ throw DomainError . cannotCreateSubdomain
133126 }
134- if let domain = rfc1123, let parent = try domain. parent ( ) {
135- return try Domain ( rfc1123: parent)
127+
128+ /// Returns the parent domain by removing the leftmost label
129+ public func parent( ) throws -> Domain ? {
130+ // Use the most specific format available
131+ if let domain = rfc1035, let parent = try domain. parent ( ) {
132+ return try Domain ( rfc1035: parent)
133+ }
134+ if let domain = rfc1123, let parent = try domain. parent ( ) {
135+ return try Domain ( rfc1123: parent)
136+ }
137+ return nil
136138 }
137- return nil
138- }
139139}
140140
141141// MARK: - Errors
142142extension Domain {
143- public enum DomainError : Error , Equatable , LocalizedError {
144- case cannotCreateSubdomain
145- case conversionFailure
146- case invalidFormat( description: String )
147-
148- public var errorDescription : String ? {
149- switch self {
150- case . cannotCreateSubdomain:
151- return " Cannot create subdomain for IP address literals "
152- case . conversionFailure:
153- return " Failed to convert "
154- case . invalidFormat( let description) :
155- return " Invalid format: \( description) "
156- }
143+ public enum DomainError : Error , Equatable , LocalizedError {
144+ case cannotCreateSubdomain
145+ case conversionFailure
146+ case invalidFormat( description: String )
147+
148+ public var errorDescription : String ? {
149+ switch self {
150+ case . cannotCreateSubdomain:
151+ return " Cannot create subdomain for IP address literals "
152+ case . conversionFailure:
153+ return " Failed to convert "
154+ case . invalidFormat( let description) :
155+ return " Invalid format: \( description) "
156+ }
157+ }
157158 }
158- }
159159}
160160
161161// MARK: - Protocol Conformances
162162extension Domain : CustomStringConvertible {
163- public var description : String { name }
163+ public var description : String { name }
164164}
165165
166166extension Domain : Codable {
167- public func encode( to encoder: Encoder ) throws {
168- var container = encoder. singleValueContainer ( )
169- try container. encode ( name)
170- }
171-
172- public init ( from decoder: Decoder ) throws {
173- let container = try decoder. singleValueContainer ( )
174- let string = try container. decode ( String . self)
175- try self . init ( string)
176- }
167+ public func encode( to encoder: Encoder ) throws {
168+ var container = encoder. singleValueContainer ( )
169+ try container. encode ( name)
170+ }
171+
172+ public init ( from decoder: Decoder ) throws {
173+ let container = try decoder. singleValueContainer ( )
174+ let string = try container. decode ( String . self)
175+ try self . init ( string)
176+ }
177177}
178178
179179extension Domain : RawRepresentable {
180- public var rawValue : String { name }
181- public init ? ( rawValue: String ) { try ? self . init ( rawValue) }
180+ public var rawValue : String { name }
181+ public init ? ( rawValue: String ) { try ? self . init ( rawValue) }
182182}
0 commit comments