Nested types produce incorrect decoders
arbus opened this issue · 1 comments
arbus commented
given the following Haskell types
data Foo =
FooOne Text
| FooTwo Bar
deriving (Generic)
deriving (Elm, ToJSON, FromJSON) via ElmStreet Foo
data Bar = Bar
{ barOne :: Int
, barTwo :: Bool
}
deriving (Generic)
deriving (Elm, ToJSON, FromJSON) via ElmStreet Bar
it encodes and decodes like so:
λ> let x = FooOne "Hello"
λ> encode x
"{\"tag\":\"FooOne\",\"contents\":\"Hello\"}"
λ> let y = FooTwo $ Bar 1 True
λ> encode y
"{\"tag\":\"FooTwo\",\"contents\":{\"two\":true,\"one\":1}}"
The generated elm code for Foo
and Bar
have the following decoder:
decodeFoo : Decoder Foo
decodeFoo =
let decide : String -> Decoder Foo
decide x = case x of
"FooOne" -> D.field "contents" <| D.map FooOne (D.index 0 D.string)
"FooTwo" -> D.field "contents" <| D.map FooTwo (D.index 0 decodeBar)
c -> D.fail <| "Foo doesn't have such constructor: " ++ c
in D.andThen decide (D.field "tag" D.string)
decodeBar : Decoder Bar
decodeBar = D.succeed Bar
|> required "one" D.int
|> required "two" D.bool
The problem is in decide
function where it assumes that the values of the contents
field will be an array. The generated decoders fail as can be seen here:
> D.decodeString ED.decodeFoo "{\"tag\":\"FooOne\",\"contents\":\"Hello\"}"
Err (Field "contents" (Failure ("Expecting an ARRAY") <internals>))
: Result D.Error ElmStreet.Types.Foo
> D.decodeString ED.decodeFoo "{\"tag\":\"FooTwo\",\"contents\":{\"two\":true,\"one\":1}}"
Err (Field "contents" (Failure ("Expecting an ARRAY") <internals>))
: Result D.Error ElmStreet.Types.Foo
chshersh commented
I'm looking into this.