Skip to content

Commit 8ae20fa

Browse files
committed
URLComponents Codable conformance
1 parent f23d554 commit 8ae20fa

File tree

2 files changed

+133
-0
lines changed

2 files changed

+133
-0
lines changed

Foundation/URLComponents.swift

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -456,3 +456,42 @@ extension URLQueryItem : _ObjectTypeBridgeable {
456456
return result!
457457
}
458458
}
459+
460+
extension URLComponents : Codable {
461+
private enum CodingKeys : Int, CodingKey {
462+
case scheme
463+
case user
464+
case password
465+
case host
466+
case port
467+
case path
468+
case query
469+
case fragment
470+
}
471+
472+
public init(from decoder: Decoder) throws {
473+
self.init()
474+
475+
let container = try decoder.container(keyedBy: CodingKeys.self)
476+
self.scheme = try container.decodeIfPresent(String.self, forKey: .scheme)
477+
self.user = try container.decodeIfPresent(String.self, forKey: .user)
478+
self.password = try container.decodeIfPresent(String.self, forKey: .password)
479+
self.host = try container.decodeIfPresent(String.self, forKey: .host)
480+
self.port = try container.decodeIfPresent(Int.self, forKey: .port)
481+
self.path = try container.decode(String.self, forKey: .path)
482+
self.query = try container.decodeIfPresent(String.self, forKey: .query)
483+
self.fragment = try container.decodeIfPresent(String.self, forKey: .fragment)
484+
}
485+
486+
public func encode(to encoder: Encoder) throws {
487+
var container = encoder.container(keyedBy: CodingKeys.self)
488+
try container.encodeIfPresent(self.scheme, forKey: .scheme)
489+
try container.encodeIfPresent(self.user, forKey: .user)
490+
try container.encodeIfPresent(self.password, forKey: .password)
491+
try container.encodeIfPresent(self.host, forKey: .host)
492+
try container.encodeIfPresent(self.port, forKey: .port)
493+
try container.encode(self.path, forKey: .path)
494+
try container.encodeIfPresent(self.query, forKey: .query)
495+
try container.encodeIfPresent(self.fragment, forKey: .fragment)
496+
}
497+
}

TestFoundation/TestCodable.swift

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -412,6 +412,99 @@ class TestCodable : XCTestCase {
412412
expectRoundTripEqualityThroughJSON(for: Measurement(value: 42, unit: UnitMass.kilograms))
413413
expectRoundTripEqualityThroughJSON(for: Measurement(value: 42, unit: UnitLength.miles))
414414
}
415+
416+
// MARK: - URLComponents
417+
lazy var urlComponentsValues: [URLComponents] = [
418+
URLComponents(),
419+
420+
URLComponents(string: "http://swift.org")!,
421+
URLComponents(string: "http://swift.org:80")!,
422+
URLComponents(string: "https://www.mywebsite.org/api/v42/something.php#param1=hi&param2=hello")!,
423+
URLComponents(string: "ftp://johnny:[email protected]:4242/some/path")!,
424+
425+
URLComponents(url: URL(string: "http://swift.org")!, resolvingAgainstBaseURL: false)!,
426+
URLComponents(url: URL(string: "http://swift.org:80")!, resolvingAgainstBaseURL: false)!,
427+
URLComponents(url: URL(string: "https://www.mywebsite.org/api/v42/something.php#param1=hi&param2=hello")!, resolvingAgainstBaseURL: false)!,
428+
URLComponents(url: URL(string: "ftp://johnny:[email protected]:4242/some/path")!, resolvingAgainstBaseURL: false)!,
429+
URLComponents(url: URL(fileURLWithPath: NSTemporaryDirectory()), resolvingAgainstBaseURL: false)!,
430+
URLComponents(url: URL(fileURLWithPath: "/"), resolvingAgainstBaseURL: false)!,
431+
URLComponents(url: URL(string: "documentation", relativeTo: URL(string: "http://swift.org")!)!, resolvingAgainstBaseURL: false)!,
432+
433+
URLComponents(url: URL(string: "http://swift.org")!, resolvingAgainstBaseURL: true)!,
434+
URLComponents(url: URL(string: "http://swift.org:80")!, resolvingAgainstBaseURL: true)!,
435+
URLComponents(url: URL(string: "https://www.mywebsite.org/api/v42/something.php#param1=hi&param2=hello")!, resolvingAgainstBaseURL: true)!,
436+
URLComponents(url: URL(string: "ftp://johnny:[email protected]:4242/some/path")!, resolvingAgainstBaseURL: true)!,
437+
URLComponents(url: URL(fileURLWithPath: NSTemporaryDirectory()), resolvingAgainstBaseURL: true)!,
438+
URLComponents(url: URL(fileURLWithPath: "/"), resolvingAgainstBaseURL: true)!,
439+
URLComponents(url: URL(string: "documentation", relativeTo: URL(string: "http://swift.org")!)!, resolvingAgainstBaseURL: true)!,
440+
441+
{
442+
var components = URLComponents()
443+
components.scheme = "https"
444+
return components
445+
}(),
446+
447+
{
448+
var components = URLComponents()
449+
components.user = "johnny"
450+
return components
451+
}(),
452+
453+
{
454+
var components = URLComponents()
455+
components.password = "apples"
456+
return components
457+
}(),
458+
459+
{
460+
var components = URLComponents()
461+
components.host = "0.0.0.0"
462+
return components
463+
}(),
464+
465+
{
466+
var components = URLComponents()
467+
components.port = 8080
468+
return components
469+
}(),
470+
471+
{
472+
var components = URLComponents()
473+
components.path = ".."
474+
return components
475+
}(),
476+
477+
{
478+
var components = URLComponents()
479+
components.query = "param1=hi&param2=there"
480+
return components
481+
}(),
482+
483+
{
484+
var components = URLComponents()
485+
components.fragment = "anchor"
486+
return components
487+
}(),
488+
489+
{
490+
var components = URLComponents()
491+
components.scheme = "ftp"
492+
components.user = "johnny"
493+
components.password = "apples"
494+
components.host = "0.0.0.0"
495+
components.port = 4242
496+
components.path = "/some/file"
497+
components.query = "utf8=✅"
498+
components.fragment = "anchor"
499+
return components
500+
}()
501+
]
502+
503+
func test_URLComponents_JSON() {
504+
for (components) in urlComponentsValues {
505+
expectRoundTripEqualityThroughJSON(for: components)
506+
}
507+
}
415508
}
416509

417510
extension TestCodable {
@@ -434,6 +527,7 @@ extension TestCodable {
434527
("test_Calendar_JSON", test_Calendar_JSON),
435528
("test_DateComponents_JSON", test_DateComponents_JSON),
436529
("test_Measurement_JSON", test_Measurement_JSON),
530+
("test_URLComponents_JSON", test_URLComponents_JSON),
437531
]
438532
}
439533
}

0 commit comments

Comments
 (0)