Я хотел бы декодировать ответ API, в котором одно из значений полей (category
) определит, как декодировать другое поле (configuration
) с использованием разных поддекодеров ,Возможно ли условное декодирование определенных полей с использованием elm-decode-трубопровода
Я был в состоянии выполнить такую вещь, используя Json.Decode.mapn
функции и функции andThen
, но мне было интересно, если есть способ сделать такую вещь, используя elm-decode-pipeline
как он имеет более приятный интерфейс API, и я буду бежать из mapn
функций в конечном счете.
minimmum и несколько тривиальный пример будет выглядеть так:
type alias Machine =
{ name : String
, specs : MachineSpecs
}
type MachineSpecs
= ElectricMachine ElectricSpecs
| MechanicalMachine MechanicalSpecs
| UnknownMachine
type alias ElectricSpecs =
{ voltage : Int
}
type alias MechanicalSpecs =
{ gears : Int
}
И некоторые действительные ответы JSON бы эти формы:
{
"name": "Foo electric machine",
"category": "electric",
"configuration": {
"voltage": 12
}
}
{
"name": "Bar mechanical machine",
"category": "mechanical",
"configuration": {
"gears": 5
}
}
{
"name": "Some machine of unknown category",
"category": "foo"
}
Я попробовал подобный подход к той, которую я использовал с функциями mapn
, но это не сработает.
decoder : Decoder Machine
decoder =
decode Machine
|> required "name" string
|> required "category" (string |> andThen catDec)
catDec : String -> Decoder MachineSpecs
catDec cat =
case cat of
"electric" ->
map ElectricMachine electricDecoder
"mechanical" ->
map MechanicalMachine mechanicalDecoder
_ ->
succeed UnknownMachine
electricDecoder : Decoder ElectricSpecs
electricDecoder =
decode ElectricSpecs
|> requiredAt [ "configuration", "voltage" ] int
mechanicalDecoder : Decoder MechanicalSpecs
mechanicalDecoder =
decode MechanicalSpecs
|> requiredAt [ "configuration", "gears" ] int
На самом деле, я не видел ни одного примера, в Интернете или документы, используя как Json.Decode.Pipeline
и andThen
в то же время, так что я не уверен, если это вообще возможно.
Я настроил онлайн пример этого вопроса, показывая, как он не может декодировать условную часть: https://runelm.io/c/3ut