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

Generic materialize function with throwable behaviour for throwable initializers #890

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

iwheelbuy
Copy link

Lets say I have some struct and some enum

enum ValueEnum: Int {
    case first = 1
    case second = 2
}

struct MyStruct {
    let valueBool: Bool?
    let valueDouble: [Double]
    let valueEnum: ValueEnum
    let valueInt: Int
    let valueString: String
}

I want to parse the struct from JSON

struct MyStruct {
    let valueBool: Bool?
    let valueDouble: [Double]
    let valueEnum: ValueEnum
    let valueInt: Int
    let valueString: String
    
    init(json: JSON) throws {
        // parse
    }
}

JSON looks this way

let json: JSON = [
    "valueString": "hello",
    "valueDictionary": [
        "valueInt": 100500
    ],
    "valueDouble": [1.1, 2.2, 3.3],
    "valueEnum": 2
]

This is an example how I'd parse it in a pure SwiftyJSON way

init(json: JSON) throws {
    valueBool = json["valueBool"].bool
    if let valueDouble = json["valueDouble"].array {
        self.valueDouble = try valueDouble
            .map({ (json) -> Double in
                if let double = json.double {
                    return double
                } else {
                    throw SwiftyJSONError.someParsingError
                }
            })
    } else {
        throw SwiftyJSONError.someParsingError
    }
    if let value = json["valueEnum"].int {
        if let valueEnum = ValueEnum(rawValue: value) {
            self.valueEnum = valueEnum
        } else {
            throw SwiftyJSONError.someParsingError
        }
    } else {
        throw SwiftyJSONError.someParsingError
    }
    if let valueInt = json["valueDictionary"]["valueInt"].int {
        self.valueInt = valueInt
    } else {
        throw SwiftyJSONError.someParsingError
    }
    if let valueString = json["valueString"].string {
        self.valueString = valueString
    } else {
        throw SwiftyJSONError.someParsingError
    }
}

My pull request allows to do it this way

init(json: JSON) throws {
    valueBool = json["valueBool"].materialize()
    valueDouble = try json["valueDouble"].materialize()
    valueEnum = try json["valueEnum"].materialize()
    valueInt = try json["valueDictionary"]["valueInt"].materialize()
    valueString = try json["valueString"].materialize()
}

My pull request is just a proposal. Please don't merge it. Lets discuss.
Maybe... I'm missing something and there is already some way to conveniently parse and throw errors.

throw factoryError(file: file, line: line)()
}
}
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

File Line Length Violation: File should contain 400 lines or less: currently contains 1546 (file_length)

func materialize<T>(file: String = #file, line: Int = #line) throws -> T where T: JSONMaterializableType {
return try T.implementation(self, factoryError(file: file, line: line))
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Trailing Whitespace Violation: Lines should not have trailing whitespace. (trailing_whitespace)

throw factoryError(file: file, line: line)()
}
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Trailing Whitespace Violation: Lines should not have trailing whitespace. (trailing_whitespace)

func materialize<T>(file: String = #file, line: Int = #line) -> T? where T: JSONMaterializableType {
return try? T.implementation(self, factoryError(file: file, line: line))
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Trailing Whitespace Violation: Lines should not have trailing whitespace. (trailing_whitespace)

}

public extension JSON {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Trailing Whitespace Violation: Lines should not have trailing whitespace. (trailing_whitespace)

}

extension String: JSONMaterializableType {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Trailing Whitespace Violation: Lines should not have trailing whitespace. (trailing_whitespace)

}

extension Int: JSONMaterializableType {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Trailing Whitespace Violation: Lines should not have trailing whitespace. (trailing_whitespace)

}

extension Double: JSONMaterializableType {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Trailing Whitespace Violation: Lines should not have trailing whitespace. (trailing_whitespace)

}

extension Bool: JSONMaterializableType {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Trailing Whitespace Violation: Lines should not have trailing whitespace. (trailing_whitespace)

// MARK: -

public protocol JSONMaterializableType {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Trailing Whitespace Violation: Lines should not have trailing whitespace. (trailing_whitespace)

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

Successfully merging this pull request may close these issues.

None yet

2 participants