thoughtbot / Argo

Functional JSON parsing library for Swift
https://thoughtbot.com
MIT License
3.49k stars 198 forks source link

Document the use of the `alternate` operator #285

Open gfontenot opened 8 years ago

gfontenot commented 8 years ago

Related: #284

Our use of Alternative is something that sticks out to me as being insanely powerful, but we don't talk about it ever. We should add some documentation around this. Ideas:

alskipp commented 8 years ago

Another use for the Alternative operator could be for supplying default values to avoid the use of Optionals in models. Here's a quick example:

struct Player {
  let id: Int, name: String, lives: Int, goldCoins: Int
}

extension Player: Decodable {
  static func decode(j: JSON) -> Decoded<Player> {
    return curry(self.init)
      <^> j <| "id"
      <*> j <| "name" <|> pure("Anonymous Player")
      <*> j <| "lives"
      <*> j <| "goldCoins" <|> pure(0)
  }
}

let playersJSON: AnyObject = [
  ["id": 1, "name": "Gertrude", "lives": 5, "goldCoins": 20],
  ["id": 2, "name": "Dave", "lives": 1],
  ["id": 3, "lives": 3],
  ["id": 4, "lives": 1, "goldCoins": 13],
]

let players: [Player]? = decode(playersJSON)
print(players!)

What do you think? If you thought it a reasonable example then something similar could be added to the included Argo Playground file.

paulyoung commented 8 years ago

I do this when the server might return null instead of an empty array.

Marcin-Kapusta commented 7 years ago

@paulyoung How are You doing this with Arrays. I've created this Issue I was trying use .success or pure without any success. My goal is similar than Yours. Server returns null for Array and I would like to convert it to just empty Array for not optional Array property.

paulyoung commented 7 years ago

@Marcin-Kapusta here's one example: https://github.com/the-grid/Portal/blob/31e406ce9319dad7fd31c073dfdb6a20d7511c3f/Portal/Models/Item.swift#L39

rob5408 commented 7 years ago

I don't know about anyone else, but I definitely needed extra parentheses to get this working...

extension Team: Decodable {
    static func decode(_ json: Argo.JSON) -> Decoded<Team> {
        return curry(Team.init)
            <^> (json <| "id" <|> pure("123"))
            <*> (json <| "name" <|> pure("Anonymous"))
    }
}

Without them I got an error "Cannot convert value of type '(Id, Name) -> Team' to expected argument type '(_) -> Team'"

(Swift 3, Argo 4.1.2, Runes 4.0.1, Curry 3.0.0)