Skip to content

Instantly share code, notes, and snippets.

@jamesmacaulay
Last active November 9, 2017 16:49
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 jamesmacaulay/eff482aa05379e9267dd1e85fbff5c6d to your computer and use it in GitHub Desktop.
Save jamesmacaulay/eff482aa05379e9267dd1e85fbff5c6d to your computer and use it in GitHub Desktop.
Json.Bidirectional.Coder hoisting subset of object's fields into a tuple https://ellie-app.com/h5Sb2g8b4a1/0
module Main exposing (main)
import Html exposing (Html, text)
import Json.Bidirectional as Json
import Json.Decode as Decode
import Json.Encode as Encode
import String
import Tuple
type Currency
= Usd
| Jpy
type alias Item =
{ name : String
, price : ( Int, Currency )
}
currencyEncoder : Currency -> Encode.Value
currencyEncoder x =
case x of
Usd ->
Encode.string "USD"
Jpy ->
Encode.string "JPY"
currencyDecoder : Decode.Decoder Currency
currencyDecoder =
Decode.string
|> Decode.andThen
(\x ->
case x of
"USD" ->
Decode.succeed Usd
"JPY" ->
Decode.succeed Jpy
_ ->
Decode.fail "invalid currency"
)
currency : Json.Coder Currency
currency =
Json.custom currencyEncoder currencyDecoder
itemConstructor : String -> Int -> Currency -> Item
itemConstructor name amount currency =
{ name = name, price = ( amount, currency ) }
item : Json.Coder Item
item =
Json.object itemConstructor
|> Json.withField "name" .name Json.string
|> Json.withField "amount" (.price >> Tuple.first) Json.int
|> Json.withField "currency" (.price >> Tuple.second) currency
root : Json.Coder Item
root =
item
|> Json.at [ "item" ]
jsonDocument : String
jsonDocument =
"""
{
"item": {
"name": "Item A",
"amount": 10,
"currency": "USD"
}
}
"""
main : Html msg
main =
let
decoded =
Json.decodeString root jsonDocument
reEncoded =
Result.map (Json.encodeString root 0) decoded
roundTripEquivalence =
decoded == (reEncoded |> Result.andThen (Json.decodeString root))
in
text <|
toString <|
{ decoded = decoded
, reEncoded = reEncoded
, roundTripEquivalence = roundTripEquivalence
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment