I'm working on a project to create a custom Decoder
to deal with non JSON data.
Data to decode can be URL
s or String
s. For example:
struct MyData: Decodable {
let server: URL
let version: String
}
In order to deal with such a type of decoding, I've implemented a class, called KeyedContainer
, that implements the KeyedDecodingContainerProtocol
.
For a String
is quite simple since I can use the following method:
func decode(_ type: String.Type, forKey key: Key) throws -> String { }
For an URL
, instead, I need to rely on the following:
func decode<T>(_ type: T.Type, forKey key: Key) throws -> T where T: Decodable { }
Within it, I do something like the following:
func decode<T>(_ type: T.Type, forKey key: Key) throws -> T where T: Decodable {
try checkCanDecodeValue(forKey: key)
guard let value = configuration[key.stringValue] else {
let context = DecodingError.Context(codingPath: codingPath, debugDescription: "TODO")
throw DecodingError.typeMismatch(type, context)
}
guard let url = URL(string: value) else {
let context = DecodingError.Context(codingPath: codingPath, debugDescription: "TODO")
throw DecodingError.valueNotFound(type, context)
}
return url as! T
}
where configuration
is a struct that is passed along to KeyedContainer
directly from the custom decoder.
Is this the right approach? What I'm not sure about is the as! T
cast in order to make the compiler happy.