I want to decode a JSON array of payload objects into List Payload where each Payload is a custom type:
type Payload
= PayloadP1 P1
| PayloadP2 P2
After decoding PayloadP1 and PayloadP2 using decoders below how do I decode Payload?
type alias P1 =
{ id : Int
, st : String
}
type alias P2 =
{ id : Int
, s1 : String
, s2 : String
}
type Payload
= PayloadP1 P1
| PayloadP2 P2
type alias PayloadQueue = List Payload
decodeP1 : Jd.Decoder P1
decodeP1 =
Jd.map2 P1
(Jd.field "id" Jd.int)
(Jd.field "st" Jd.string)
decodeP2 : Jd.Decoder P2
decodeP2 =
Jd.map3 P2
(Jd.field "id" Jd.int)
(Jd.field "p1" Jd.string)
(Jd.field "p2" Jd.string)
decodePayload =
Jd.field ".type" Jd.string
|> Jd.andThen decodePayload_
{-
decodePayload_ : String -> Jd.Decoder Payload
decodePayload_ ptype =
case ptype of
"P1" -> decodeP1
"P2" -> decodeP2
-}
json_str = """[
{".type" : "P1", "id" : 1, "st" : "st"},
{".type" : "P2", "id" : 2, "p1" : "p1", "p2" : "p2"},
]"""
You need to wrap
P1andP2inPayloadP1andPayloadP2respectively in order to return a common type from each branch, which you can do usingmap. Then you also need to account for the possibility that thetypefield is neitherP1orP2. In that case you can either provide a default or return an error usingfail. I've done the latter below.