sveinhal
(Svein Halvor Halvorsen)
1
To facilitate testing, I've made a custom Decoder called RandomDecoder which implements all the various decode(_ type:) methods by returning random numbers, strings and bools. Its UnkeyedContainer also returns a random count, and decodeNil randomly makes sure that nullable values are sometimes actually nil.
I works like so:
struct Foo: Codable {
var bar: String
var quz: Double
var fiz: [String]
var lax: Bool?
}
let foos = try [Foo](from: RandomDecoder())
let json = try JSONEncoder().encode(foos)
print(String(data: json, encoding: .utf8)!)
// [{"bar":"O9pjMIz3itWo","quz":101.11795860911604,"fiz":["1hBKQ14WfDF67yy","CGoPftgVIQ8BCDZ","XhLQelYzYHXxji5d","Wdp69iIgpnOv03","1gY7Qq19j"],"lax":true},{"bar":"F9vkgbsB2EJjf3ip","quz":108.47102159207577,"fiz":["QgzzuUu"],"lax":false}]
However, when "decoding" e.g URLs, I don't want to generate a random string and parse it as a URL, since that almost certainly will generate a non-valid URL. I'd rather provide a hook for types to generate their own random instances, by e.g. conforming to a protocol like RandomInstantiable. Then URL could eg. generate randoms paths and add it to "example.com" or something to generate true random URLs.
However, how do I implement the following in a way that works?
func decode<T: Decodable>(_ type: T.Type, forKey key: Key) throws -> T {
if T is RandomInstatiable { // this doesn't work
return T.randomInstance() // T is just Decodable here
else {
return try T(from: RandomDecoder(using: &generator))
}
}
Nevin
2
Have you tried this?
if let t = type as? RandomInstantiable.Type
3 Likes
Hello. Try this:
func decode<T: Decodable>(_ type: T.Type, forKey key: Key) throws -> T {
if let type = T.self as? RandomInstatiable.Type {
return type.randomInstance() as! T
else {
return try T(from: RandomDecoder(using: &generator))
}
}
(inspiration)
1 Like
sveinhal
(Svein Halvor Halvorsen)
4
Thanks, both! I could have sworn I had tried that already, and gotten some error wrt .Type or .Protocol or whatever. But I’m probably just mixing things up ¯_(ツ)_/¯
I’ll try that (again) as soon as I get to a real computer. Again, thanks!
sveinhal
(Svein Halvor Halvorsen)
5
That worked perfectly. I'm now getting useful random URLs, Dates, etc. Tbh, I'm not sure what I did to mess it up before, but I'm glad it works now! Thanks again to both of you <3
CTMacUser
(Daryle Walker)
6
I guess that T always follows the static typing in the function's generic descriptor, even when T is proven to have other conformances dynamically in-function. The output from the as? creates a new type expression with the updated interface.
1 Like