Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Using non final class Decodable #118

Closed
marcmatta opened this issue Apr 13, 2016 · 4 comments
Closed

Using non final class Decodable #118

marcmatta opened this issue Apr 13, 2016 · 4 comments
Labels
Milestone

Comments

@marcmatta
Copy link

I have an issue since i last updated my pods and Himotoki got upgraded to 2.0.0.

I no longer can use DecodedType and I have the following scenario I'd appreciate if you can help me fix.

I am subclassing a class which I need to be decodable like such:

class A: Decodable {
    var type : Int = 0
    var title: String = ""

    init (e: Extractor) {
        type = try! e <| "type"
        title = try! e <| "title"
    }

    static func decode(e: Extractor) throws -> A {
        let type : Int = try e <| "type"
        switch type {
        case 0:
            return B(e: e)
        case 1:
            return C(e: e)
        case 2:
            return A(e: e)
        }
    }
}

class B: A {
    var total : Double = 0.0
    override init(e: Extractor) {
        total = try! e <| "total"
        super.init(e: e)
    }
}

class C: A {
    var link : String = ""
    override init(e: Extractor) {
        link = try! e <| "link"
        super.init(e: e)
    }
}

I now have a compiler error on this line static func decode(e: Extractor) throws -> A which says Method 'decode' in non-final class 'A' must return 'Self' to conform to protocol 'Decodable'

Thank you for your help in advance! Great library 👍 !

@ikesyo ikesyo added this to the 2.0.0 milestone Apr 25, 2016
@ikesyo
Copy link
Owner

ikesyo commented Apr 25, 2016

I'm sorry for the inconvenience. I'm reconsidering about DecodedType associatedtype and the class cluster pattern you described here: #122

@tarunon
Copy link
Contributor

tarunon commented Apr 27, 2016

I guess we can use castOrFail function in this case.

internal func castOrFail<T>(any: Any?) throws -> T {
guard let result = any as? T else {
throw typeMismatch("\(T.self)", actual: any, keyPath: nil)
}
return result
}

And new decode function is,

static func decode(e: Extractor) throws -> Self {
    let type : Int = try e <| "type"
    switch type {
    case 0:
        return try castOrFail(B(e: e))
    case 1:
        return try castOrFail(C(e: e))
    case 2:
        return try castOrFail(A(e: e))
    }
}

I believe it would work well.

@marcmatta
Copy link
Author

okay thanks for your help!

@ikesyo
Copy link
Owner

ikesyo commented Jun 17, 2016

I'm sorry for the late response. I'm convinced that make castOrFail function public should be good enough for now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants