Last active
May 4, 2020 12:56
-
-
Save farzadshbfn/22664e4ea226b942c4a9de6a37c0c119 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
struct User: Codable { | |
typealias Id = String | |
let id: Id | |
let cellNumber: CellNumber | |
let status: Status | |
enum Status { | |
case notRegistered | |
case registered(profile: Profile) | |
} | |
struct Profile: Codable { | |
let name: String | |
let lastName: String | |
let email: Email? | |
let isEmailVerified: Bool | |
private enum CodingKeys: String, CodingKey { | |
case name | |
case lastName = "last_name" | |
case email | |
case isEmailVerified = "is_email_verified" | |
} | |
} | |
private enum CodingKeys: String, CodingKey { | |
case id | |
case cellNumber = "cell_number" | |
case isRegistered = "is_registered" | |
case profile | |
} | |
init(from decoder: Decoder) throws { | |
let container = try decoder.container(keyedBy: CodingKeys.self) | |
id = try container.decode(Id.self, forKey: .id) | |
cellNumber = try container.decode(CellNumber.self, forKey: .cellNumber) | |
let isRegistered = try container.decode(Bool.self, forKey: .isRegistered) | |
status = isRegistered ? try .registered(profile: container.decode(Profile.self, forKey: .profile)) : .notRegistered | |
} | |
func encode(to encoder: Encoder) throws { | |
var container = encoder.container(keyedBy: CodingKeys.self) | |
try container.encode(id, forKey: .id) | |
try container.encode(cellNumber, forKey: .cellNumber) | |
switch status { | |
case .notRegistered: | |
try container.encode(false, forKey: .isRegistered) | |
case .registered(let profile): | |
try container.encode(true, forKey: .isRegistered) | |
try container.encode(profile, forKey: .profile) | |
} | |
} | |
} | |
struct CellNumber: Codable { | |
let digits: String | |
init(from decoder: Decoder) throws { | |
let container = try decoder.singleValueContainer() | |
let rawDigits = try container.decode(String.self) | |
// validate rawDigits by some Regex maybe? and throw appropriate errors? | |
// or extract CountryCode and AreaCode and save them in another way? | |
self.digits = rawDigits | |
} | |
func encode(to encoder: Encoder) throws { | |
var container = encoder.singleValueContainer() | |
try container.encode(digits) | |
} | |
} | |
struct Email: Codable { | |
let address: String | |
init(from decoder: Decoder) throws { | |
let container = try decoder.singleValueContainer() | |
let rawAddress = try container.decode(String.self) | |
// validate rawAddress by some Regex maybe? and throw appropriate errors? | |
self.address = rawAddress | |
} | |
func encode(to encoder: Encoder) throws { | |
var container = encoder.singleValueContainer() | |
try container.encode(address) | |
} | |
} | |
// MARK:- User Helper methods | |
extension User { | |
var isRegistered: Bool { | |
return status.isRegistered | |
} | |
var profile: Profile? { | |
return status.profile | |
} | |
} | |
// MARK:- User.Status helper methods | |
extension User.Status { | |
fileprivate var isRegistered: Bool { | |
switch self { | |
case .registered: return true | |
case .notRegistered: return false | |
} | |
} | |
fileprivate var profile: User.Profile? { | |
switch self { | |
case .registered(let profile): return profile | |
case .notRegistered: return nil | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment