Skip to content

Instantly share code, notes, and snippets.

@nh7a
Last active July 17, 2019 18:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nh7a/2a3deed252a8443b84d1e95256dd3b46 to your computer and use it in GitHub Desktop.
Save nh7a/2a3deed252a8443b84d1e95256dd3b46 to your computer and use it in GitHub Desktop.
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