utahiosmac / Marshal

Marshaling the typeless wild west of [String: Any]
MIT License
698 stars 63 forks source link

Abiguous use of operator/function with enum #103

Closed BenchR267 closed 7 years ago

BenchR267 commented 7 years ago

Hi!

I experienced a small problem when using enums as ValueTypes. I have an enum in a project defined as the following:

enum Week: Int {
    case all = 0, even, odd
}

I implemented the ValueType extension as the following:

extension Week: ValueType {
    public static func value(from object: Any) throws -> Week {
        guard let raw = object as? RawValue else {
            throw MarshalError.typeMismatch(expected: RawValue.self, actual: type(of: object))
        }
        guard let week = Week(rawValue: raw) else {
            throw Error.outOfBounds(raw)
        }
        return week
    }
}

When using this in a type that has a Week property, I get the compiler error 'ambiguous use of X' where X is either <| or value(for:).

I fixed it by using this code in my type that is using Week, but the solution is not that satisfiying. Do you have any other ideas?

let rawWeek: Int = try object <| "week"
guard let week = Week(rawValue: rawWeek) else {
    throw Week.Error.outOfBounds(rawWeek)
}
self.week = week

Thanks in advance!

bwhiteley commented 7 years ago

@BenchR267 enums with raw values are automatically ValueTypes.

Look for RawRepresentable in MarshaledObject.swift to see how this is done.

BenchR267 commented 7 years ago

Ah thanks, that explains the message. In this case this works great, but I have another enum with a slightly more complex mapping logic. Is it somehow possible to overwrite the behaviour?

bwhiteley commented 7 years ago

I can't think of a way to do that short of what you're already doing (pull out the raw value and do the mapping). We would need to add something like this to achieve what you want: https://github.com/utahiosmac/Marshal/issues/73#issuecomment-258433175

BenchR267 commented 7 years ago

Yeah, that would solve this case. Thanks for your answers! I'll close this issue since my original question is answered. 😸