Last active
July 17, 2019 18:30
-
-
Save nh7a/2a3deed252a8443b84d1e95256dd3b46 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public protocol TypedIdentifier: RawRepresentable {} | |
extension TypedIdentifier { | |
public init(_ rawValue: RawValue) { | |
self.init(rawValue: rawValue)! | |
} | |
} | |
extension TypedIdentifier where RawValue: Encodable { | |
public func encode(to encoder: Encoder) throws { | |
var container = encoder.singleValueContainer() | |
try container.encode(rawValue) | |
} | |
} | |
extension TypedIdentifier where RawValue: Decodable { | |
public init(from decoder: Decoder) throws { | |
let container = try decoder.singleValueContainer() | |
self.init(try container.decode(RawValue.self)) | |
} | |
} | |
extension TypedIdentifier where RawValue: Comparable { | |
public static func < (lhs: Self, rhs: Self) -> Bool { | |
return lhs.rawValue < rhs.rawValue | |
} | |
} | |
extension TypedIdentifier where RawValue: AdditiveArithmetic { | |
public static func -= (lhs: inout Self, rhs: Self) { | |
lhs = Self(lhs.rawValue - rhs.rawValue) | |
} | |
public static func - (lhs: Self, rhs: Self) -> Self { | |
return Self(lhs.rawValue - rhs.rawValue) | |
} | |
public static func += (lhs: inout Self, rhs: Self) { | |
lhs = Self(lhs.rawValue + rhs.rawValue) | |
} | |
public static func + (lhs: Self, rhs: Self) -> Self { | |
return Self(lhs.rawValue + rhs.rawValue) | |
} | |
public static var zero: Self { | |
return Self.init(rawValue: RawValue.zero)! | |
} | |
} | |
// Sample | |
public struct Milliseconds: Codable, AdditiveArithmetic, Comparable, TypedIdentifier { | |
public let rawValue: Int64 | |
public init(rawValue: RawValue) { | |
self.rawValue = rawValue | |
} | |
} | |
struct Course: Codable { | |
var id: ID | |
var name: Name | |
var partner: Partner? | |
var milliseconds: Milliseconds? | |
struct Partner: Codable { | |
var id: ID | |
var name: Name | |
struct ID: Codable, TypedIdentifier { var rawValue: Int } | |
struct Name: Codable, TypedIdentifier { var rawValue: String } | |
} | |
struct ID: Codable, TypedIdentifier { var rawValue: Int } | |
struct Name: Codable, TypedIdentifier { var rawValue: String } | |
} | |
// Encoding | |
let partner = Course.Partner(id: Course.Partner.ID(1), name: Course.Partner.Name("par")) | |
let course1 = Course(id: Course.ID(1), name: Course.Name("foo"), partner: partner, milliseconds: Milliseconds(1234)) | |
let data1 = try JSONEncoder().encode(course1) | |
let json1 = String(data: data1, encoding: .utf8) | |
assert(course1.name.rawValue == "foo") | |
assert(course1.id == Course.ID(1)) | |
assert(course1.partner!.id == Course.Partner.ID(1)) | |
assert(course1.milliseconds == Milliseconds(1234)) | |
assert(json1 == #"{"id":1,"milliseconds":1234,"name":"foo","partner":{"id":1,"name":"par"}}"#) | |
// Decoding | |
let json2 = #"{"id":2,"name":"bar","partner":{"id":2,"name":"dar"}}"# | |
let data2 = json2.data(using: .utf8)! | |
let course2 = try JSONDecoder().decode(Course.self, from: data2) | |
assert(course2.name.rawValue == "bar") | |
assert(course2.id.rawValue == 2) | |
assert(course2.partner!.id.rawValue == 2) | |
// Milliseconds | |
assert(Milliseconds(10) + Milliseconds(100) == Milliseconds(110)) | |
assert(Milliseconds(1) < Milliseconds(2)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment