steamclock / netable

A Swift library for encapsulating network APIs using Codable in a type-oriented way.
MIT License
99 stars 3 forks source link

add support for fallback decoding type #90

Closed brendanlensink closed 3 years ago

brendanlensink commented 3 years ago

For #66

I'm not super happy with this implementation, it feels a little strange to put this in NetableError, but I'm not really sure there's a better way.

nbrooke commented 3 years ago

I can definitely imagine better interfaces when unfetter by constraint like actually having to make them work in all cases 😄, like ideally you'd want to the fallback to be a bit more first class, more like a sibling of the main result and the error:

struct FallbackResult {
   case success(FinalResource)
   case fallback(FallbackResource)
   case failure(NetableError)
}

But if there's a good way to squeeze something like that into the existing main interface without huge API disruption and lots of annoyance for requests that DIDN'T use a fallback, I can't think what it'd be.

Best I can think is maybe providing some sort of utility to turn a result with that buried in the error into something more like that like:

extension Result: where Error == NetableError {
    var fallbackResult : FallbackResult {
            switch result {
             case .success(let response):
                 return .success(response)
             case .failure(let error):
                 switch error {
                 case .fallbackDecode(let fallbackResponse):
                    return .fallback(fallbackResponse)
                 default:
                    return .failure(error)
                 }
             }    
     }
}

that might make it a little cleaner to use, but I'm not Sure it's worth it, nor am I sure about how to get all the associated types and where clauses and so on to line up correctly to make that actually work.

This seems like a reasonable implementation of the simple version of this, so might be better off just trying it like this for a while and see what happens, rather than trying to get too clever right out the gate. Something like the above would be trivial to add in for one project if it's creating a lot of pain.

brendanlensink commented 3 years ago

Okay, lets go with the simple solution for now and revisit this after we get to use it in the wild for a little while 🚀