I want to write an enum like Optional, but when I try to cast Codable value "a" to Optionally, it always failed with warning: "Cast from 'any Codable' (aka 'any Decodable & Encodable') to unrelated type 'Optionally' always fails". However, using the system Optional will not have corresponding warnings. What's the difference? How to fix my code?
public enum Optionally<T> {
case none
case value(T)
}
extension Optionally: Codable where T: Codable {
public init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
if let value = try? container.decode(T.self) {
self = .value(value)
} else {
self = .none
}
}
public func encode(to encoder: Encoder) throws {
if case .value(let value) = self {
var container = encoder.singleValueContainer()
try container.encode(value)
}
}
}
var a: Codable = Optionally<Int>.none
switch a {
case let o as Optional<Any>: // no warning!
if case .none = o {
print("it's none")
}
case let b as Optionally<Any>: // warning: Cast from 'any Codable' (aka 'any Decodable & Encodable') to unrelated type 'Optionally<Any>' always fails
print("it's optionally")
default:
print("not optionally")
}