TL;DR: I want to decode types differently based on whether they conform to a protocol on top of "Decodable". I've figured out how to get keyed containers to decode these types, but can't figure out how to do the same for un-keyed and single value containers. Is it possible?
--- I have written some code that generates arbitrary values given a Decodable type. E.g.: struct User: Decodable { let id: Int let name: String } dump(User.arbitrary) // ▿ User // - id: 787375 // - name: "服쎱竺观듰믻뜪킲啨磟°" This works great! But the ability to override ".arbitrary" on a per-value basis would be much better. Something like: protocol Arbitrary: Decodable { static var arbitrary: Self { get } } struct User: Arbitrary { static var arbitrary: User { return User( id: Int(arc4random_uniform(100)), name: Fake.names[Int(arc4random_uniform(UInt32(Fake.names.count)))] ) } } dump(User.arbitrary) // ▿ User // - id: 43 // - name: "A. Anypenny" This solves the problem for root, static calls (more on static vs. dynamic dispatch in a bit). So what about nested instances? struct Project: Decodable { let owner: User } dump(Project.arbitrary) // ▿ Project // ▿ owner: User // - id: 464786 // - name: "뗗涮ऒꂆ鳔ᩘꦞ꺰䙢覧똮漽翮귦ꜛ●㬪ⴾ枵⿵먳⏈彲≲芁۫⨸콬蘆윰拺握ஷ䰒" Oof. Well luckily I've found that I can extend "KeyedDecodingContainer" and convince the decoder to use my protocol: extension KeyedDecodingContainer { public func decode<T>(_ type: T.Type, forKey key: Key) throws -> T where T: Arbitrary { return T.arbitrary } } dump(Project.arbitrary) // ▿ Project // ▿ owner: User // - id: 76 // - name: "C. Doodler" Unfortunately I've had no such luck convincing un-keyed containers to decode using this protocol: dump([User].arbitrary) // ▿ 2 elements // ▿ User // - id: 980813 // - name: "㎜⽪羋⢢" // ▿ User // - id: -216180 // - name: "橿鰉疍旱콠싺힞㘇" ("[Int: User].arbitrary" fails similarly, though I think "Dictionary" is technically a keyed container...) I've tried adding similar "decode" functions as I did on the keyed container, but they don't seem to get called. Now back to the static dispatch of "User.arbitrary". Any interface that takes a "T: Decodable" is going to dynamically dispatch to the single value decoder and bypass my overload all over again :( (For un-keyed containers, I found that I could add extensions all day long to "Array where Element: Arbitrary", "Optional where Wrapped: Arbitrary", etc., but these too would only work from root-level static dispatch.) My hope is I've overlooked something in the decodable interfaces that would allow my un-keyed and single value containers to decode "Arbitrary" data differently than "T: Decodable". Can anyone help me make my hopes come true? --- Stephen _______________________________________________ swift-users mailing list swift-users@swift.org https://lists.swift.org/mailman/listinfo/swift-users