I am trying to define a Currency
type that would prevent numeric and alphabetic currency codes from getting mixed up:
public protocol ISO4217Type {}
public enum ISO4217Alpha: ISO4217Type {}
public enum ISO4217Num: ISO4217Type {}
public struct Currency<T: ISO4217Type> {
public let value: String
}
extension Currency where T == ISO4217Alpha {
public init?(value: String) {
let isLetter = CharacterSet.letters.contains
guard value.unicodeScalars.all(isLetter) else { return nil }
self.value = value
}
}
extension Currency where T == ISO4217Num {
public init?(value: String) {
let isDigit = CharacterSet.decimalDigits.contains
guard value.unicodeScalars.all(isDigit) else { return nil }
self.value = value
}
}
This works great. Now, is it possible to add a Codable
conformance that would throw a decoding error when trying to decode a currency code with the wrong payload? (For example, decoding USD
as a numeric currency code.)
The key revelation was that it’s possible to customize the behaviour using static functions on the phantom type: