Skip to content

Instantly share code, notes, and snippets.

@stepheneb
Last active May 21, 2019 13:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save stepheneb/6f89f5587374a9098539081007e1b42e to your computer and use it in GitHub Desktop.
Save stepheneb/6f89f5587374a9098539081007e1b42e to your computer and use it in GitHub Desktop.
module Decode2 exposing (Images, Part, Status(..), flags, images, jsonFlags, jsonStatus, jsonImages, jsonName, jsonPart, jsonParts, jsonPartInvalid, name, part, status)
import Json.Decode as D
-- Inspired by Joël Quenneville's article:
-- https://thoughtbot.com/blog/5-common-json-decoders
type alias Flags =
{ parts : List Part
, images : Images
}
type alias Part =
{ name : String
, status : Status
}
type Status
= Queued
| Started
| Complete
type alias Images =
{ wetPinkTulipSmall : String
, fivePointedStar : String
}
jsonStatus =
""" { "status": "Started" } """
jsonName =
""" { "name": "widget" } """
jsonPart = """ { "name": "widget", "status": "Started" } """
jsonPartInvalid = """ { "name": "widget", "status": "Empty" } """
jsonParts = """ [ { "name": "flywheel", "status": "Queued" }, { "name": "widget", "status": "Started" } ] """
jsonImages = """ { "wetPinkTulipSmall": "wet-pink-tulip-small.7a719004.jpg", "fivePointedStar": "Five-pointed_star.e025873b.svg" } """
jsonFlags = """ { "parts": [ { "name": "flywheel", "status": "Queued" }, { "name": "widget", "status": "Started" } ], "images": { "wetPinkTulipSmall": "wet-pink-tulip-small.7a719004.jpg", "fivePointedStar": "Five-pointed_star.e025873b.svg" } } """
parseStatus : String -> Result String Status
parseStatus string =
case string of
"Queued" -> Ok Queued
"Started" -> Ok Started
"Complete" -> Ok Complete
_ -> Err ("Invalid status: " ++ string)
fromResult : Result String a -> D.Decoder a
fromResult result =
case result of
Ok a -> D.succeed a
Err errorMessage -> D.fail errorMessage
status : D.Decoder Status
status =
(D.field "status" D.string) |> D.andThen (fromResult << parseStatus)
name : D.Decoder String
name =
D.field "name" D.string
part : D.Decoder Part
part =
D.map2 Part
(name)
(status)
images : D.Decoder Images
images = D.map2 Images
(D.field "wetPinkTulipSmall" D.string)
(D.field "fivePointedStar" D.string)
flags : D.Decoder Flags
flags = D.map2 Flags
(D.field "parts" (D.list part))
(D.field "images" images )
-- import Json.Decode as D
-- import Decode2 exposing (..)
--
-- D.decodeString status jsonStatus
-- > Ok Started : Result D.Error Status
--
-- D.decodeString name jsonName
-- > Ok "widget" : Result D.Error String
--
-- D.decodeString part jsonPart
-- > Ok { name = "widget", status = Started }
-- > : Result D.Error Part
--
-- D.decodeString part jsonPartInvalid
-- > Err (Failure ("Invalid status: Empty") <internals>)
-- > : Result D.Error Part
--
-- D.decodeString (D.list part) jsonParts
-- > Ok [{ name = "flywheel", status = Queued },{ name = "widget", status = Started }]
-- > : Result D.Error (List Part)
--
-- D.decodeString images jsonImages
-- > Ok { fivePointedStar = "Five-pointed_star.e025873b.svg", wetPinkTulipSmall = "wet-pink-tulip-small.7a719004.jpg" }
-- > : Result D.Error Images
--
-- D.decodeString flags jsonFlags
-- Ok { images = { fivePointedStar = "Five-pointed_star.e025873b.svg", wetPinkTulipSmall = "wet-pink-tulip-small.7a719004.jpg" }, parts = [{ name = "flywheel", status = Queued },{ name = "widget", status = Started }] }
-- : Result D.Error Flags
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment