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

Hmmm. What should these do... #18

Open
dnedrow opened this issue Jul 31, 2018 · 6 comments
Open

Hmmm. What should these do... #18

dnedrow opened this issue Jul 31, 2018 · 6 comments

Comments

@dnedrow
Copy link

dnedrow commented Jul 31, 2018

Given the following JSON...

{
  "code" : "SUCCESS",
  "positions" : [ {
    "asOf" : "2018-03-30T04:00:00.000Z",
    "description" : "***Euro ",
    "shortName" : "CASH - EURO",
    "tradeActions" : [ ]
  } ]
}

Codable conversion

The default Codable conversion for this using command line baby is...

struct MyModel: Codable {
    let code: String
    struct Position: Codable {
        let asOf: Date
        let description: String
        let shortName: String
        let tradeActions: [Any] //TODO: Specify the type to conforms Codable protocol
    }
    let positions: [Position]
}

array-object-map and enum-properties issues

My question revolves around the TODO. In this case, the values of the tradeActions array are items from an enumerated set, TradeAction. The TradeAction enum has members like "SELL" and "BUY".

The baby help seems to indicate that I can specify the type of the tradeActions array, and also declare the TradeAction enum.

So here's the baby command line I used...

baby -i t01short.json --codable --model-type struct --model-name DWMPositionsModel --json-dictionary-name "[String: Any]" --convert-from-snake-case --array-object-map "tradeActions: [TradeAction]" --enum-properties "type, TradeAction[BUY_MORE, BUY_TO_CLOSE]"

My expectation is that I would receive something similar to the following...

struct MyModel: Codable {
    let code: String
    struct Position: Codable {
        let asOf: Date
        let description: String
        let shortName: String
        let tradeActions: [TradeAction]
    }
    let positions: [Position]
    enum TradeAction {
        case BUY_MORE
        case BUY_TO_CLOSE
    }
}

However, the output is identical to the initial Codable conversion.

The array-object-map and enum-properties don't appear to actually do anything. Or am I not using them right? I see the same behavior when using CuteBaby.

@nixzhu
Copy link
Owner

nixzhu commented Jul 31, 2018

@dnedrow Hi, I think the issue is that tradeActions is an empty array, baby can not infer it's type. And Array Object Map is only work for object array (not number or string array).

If you change the json to

{
  "code": "SUCCESS",
  "positions": [
    {
      "asOf": "2018-03-30T04:00:00.000Z",
      "description": "***Euro ",
      "shortName": "CASH - EURO",
      "tradeActions": [
        "BUY_MORE",
        "BUY_TO_CLOSE"
      ]
    }
  ]
}

with Enum Properties: tradeActions, you can get

struct DWMPositionsModel: Codable {
    let code: String
    struct Position: Codable {
        let asOf: Date
        let description: String
        let shortName: String
        enum TradeActions: String, Codable {
            case bUYMORE = "BUY_MORE"
            case bUYTOCLOSE = "BUY_TO_CLOSE"
        }
        let tradeActions: [TradeActions]
    }
    let positions: [Position]
}

It's not perfect but you can modify it later.

@nixzhu
Copy link
Owner

nixzhu commented Jul 31, 2018

@dnedrow Maybe it's better to do it as a computed property (with Property Map: tradeActions: _tradeActions and Enum Properties:tradeActions[sell:SELL,buy:BUY]), you will get:

struct DWMPositionsModel: Codable {
    let code: String
    struct Position: Codable {
        let asOf: Date
        let description: String
        let shortName: String
        enum TradeActions: String, Codable {
            case sell = "SELL"
            case buy = "BUY"
        }
        let _tradeActions: [TradeActions]
        private enum CodingKeys: String, CodingKey {
            case asOf
            case description
            case shortName
            case _tradeActions = "tradeActions"
        }
    }
    let positions: [Position]
}

Now, you can modify it as follow:

struct DWMPositionsModel: Codable {
    let code: String
    struct Position: Codable {
        let asOf: Date
        let description: String
        let shortName: String
        enum TradeAction: String, Codable { // modify enum name
            case sell = "SELL"
            case buy = "BUY"
        }
        let _tradeActions: [String] // modify type
        var tradeActions: [TradeAction] { // add a new computed property
            return _tradeActions.compactMap({ TradeAction(rawValue: $0) })
        }
        private enum CodingKeys: String, CodingKey {
            case asOf
            case description
            case shortName
            case _tradeActions = "tradeActions"
        }
    }
    let positions: [Position]
}

If the TradeAction has some new cases in the future, your old model will not break.

@dnedrow
Copy link
Author

dnedrow commented Jul 31, 2018

That's an interesting solution. Thanks for the clarification.

Can you enable the Wiki for baby? I'd like to post examples for others that may have similar problems.

@dnedrow
Copy link
Author

dnedrow commented Jul 31, 2018

Or maybe it would be better if I created a markdown file of examples and submitted it as a PR here. That way it would be available when the developer downloads the code.

@nixzhu
Copy link
Owner

nixzhu commented Jul 31, 2018

@dnedrow Wiki enabled, welcome to post your examples. I'm sorry Baby has not much document.

@nixzhu
Copy link
Owner

nixzhu commented Jul 31, 2018

@dnedrow PR is also welcome.

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

No branches or pull requests

2 participants