danthorpe / Money

Swift value types for working with money & currency
MIT License
933 stars 91 forks source link

Possible to extend Money to conform to `Decodable`? #35

Open irace opened 8 years ago

irace commented 8 years ago

I’m trying to get Money to conform to Decodable, but it doesn’t seem possible.

1) You can’t directly extend Money (“Constrained extension must be declared on the unspecialized generic type _Money with constraints specified by a 'where' clause”).

2) You also can’t constrain an extension and specify that the constrained extension conforms to a protocol, e.g.:

extension _Money where C == Currency.Local: Decodable {
}

This is unfortunately just a Swift compiler limitation, this has already been promised in Swift 3.0.

Any ideas?

danthorpe commented 8 years ago

Hi @irace, thanks for the suggestion. I'll take a look into it, this week hopefully.

_Money does conform to ValueCoding - so perhaps at a minimum it should be possible to get Decodable support via some indirection.

danthorpe commented 8 years ago

So.... just been looking into this. Not really sure how I can make MoneyType conform to Decodable in a way that will be generally useful. Different sources of JSON would likely be structured differently.

@irace if you're still interested in this, can you provide a bit more information about what you're trying to do, or how you envisage using Money?

irace commented 8 years ago

Usage would be a model object like:

struct Transaction {
    let price: Money
}

extension Transaction: Decodable {
    static func decode(object: AnyObject) throws -> Transaction {
        return try Transaction(price: object => "price")
    }
}

This would be possible if one could extend Money to conform to Decodable in user-space.

I’m not suggesting that Decodable support be added to the Money library, merely that Money be extendable at all. This would be possible if Money was just a regular struct as opposed to an alias to a generic type, but I understand that there are benefits to doing it this way.

Might be worth just not worrying about until Swift 3.0 is out and it can be worked around as per my original description.

danthorpe commented 8 years ago

Arr - I see what you're getting at!

There is another issue here about creating values if given the currency code as a string, which is totally not as I've written this framework at all. I've been thinking of how to make that work, (conforming to LiteralStringConvertible essentially). In which case, this would then be trivial. The problem, and it's rather intrinsic to the way _Money works, is that the currency is the type. So, this means working with _Money<C> directly, which more than likely is not what consumers want to do.

Potentially, I'll re-write the entirely library different to be able to accommodate this kind of usage, but will probably have to wait until Swift 3.0