Skip to content

Instantly share code, notes, and snippets.

@rofrol
Created April 11, 2018 13:21
Show Gist options
  • Save rofrol/c3ec22301508dbeaccc9f9c701ae6884 to your computer and use it in GitHub Desktop.
Save rofrol/c3ec22301508dbeaccc9f9c701ae6884 to your computer and use it in GitHub Desktop.
Full example from http://folkertdev.nl/blog/elm-messy-json-value/ updated to elm 0.18
module Main exposing (..)
import Html exposing (text)
import Json.Decode as Decode exposing (..)
type FormField
= InputField Input
| DecimalField Decimal
| SpecialField String
type alias Input =
{ name : String
, class : Maybe String
, default : String
, type_ : String
}
type alias Decimal =
{ name : String
, class : Maybe String
, default : Float
, type_ : String
}
-- JSON HELPERS
withDefault : a -> Decoder a -> Decoder a
withDefault default decoder =
oneOf
[ decoder
, succeed default
]
(|:) : Decoder (a -> b) -> Decoder a -> Decoder b
(|:) =
map2 (<|)
serverResponse : String
serverResponse =
"""
{
"url": {
"class": "input",
"type": "text",
"default": "test"
}
}
"""
partialDecodeFormField : Decoder (List ( String, Value ))
partialDecodeFormField =
keyValuePairs value
feedName :
(a -> Decoder b)
-> a
-> Value
-> Result String b
feedName decoder name value =
decodeValue (decoder name) value
-- takes the name from the key and uses it in object construction
feedNameL :
(a -> Decoder b)
-> List ( a, Value )
-> List (Result String b)
feedNameL decoder elements =
List.map (\( name, value ) -> feedName decoder name value) elements
decodeList : Decoder (List (Result String FormField))
decodeList =
map (feedNameL decodeFormField) partialDecodeFormField
decodeFormField : String -> Decoder FormField
decodeFormField name =
if name == "special" then
succeed (SpecialField name)
else
field "type" string
|> andThen
(\type_ ->
let
constructDecimal class default =
DecimalField <| Decimal name class default type_
constructInput class default =
InputField <| Input name class default type_
in
case type_ of
"decimal" ->
succeed constructDecimal
|: maybe (field "class" string)
|: withDefault 0 (field "default" float)
_ ->
succeed constructInput
|: maybe (field "class" string)
|: withDefault "" (field "default" string)
)
main : Html.Html msg
main =
decodeString decodeList serverResponse
|> toString
|> text
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment