avh4 / elm-decode-pipeline

A pipeline-friendly library for building decoders.

Home Page:http://package.elm-lang.org/packages/NoRedInk/elm-decode-pipeline/latest

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

elm-decode-pipeline

A library for building decoders using the pipeline (|>) operator and ordinary function calls.

Motivation

It's common to decode into a record that has a type alias. Here's an example of this from the object3 docs:

type alias Job = { name : String, id : Int, completed : Bool }

point : Decoder Job
point =
  object3 Job
    ("name" := string)
    ("id" := int)
    ("completed" := bool)

This works because a record type alias can be called as a normal function. In that case it accepts one argument for each field (in whatever order the fields are declared in the type alias) and then returns an appropriate record built with those arguments.

The objectN decoders are straightforward, but require manually changing N whenever the field count changes. This library provides functions designed to be used with the |> operator, with the goal of having decoders that are both easy to read and easy to modify.

Examples

Here is a decoder built with this library.

import Json.Decode exposing (int, string, float, Decoder)
import Json.Decode.Pipeline exposing (decode, required, optional, hardcoded)


type alias User =
  { id : Int
  , email : String
  , name : String
  , percentExcited : Float
  }


userDecoder : Decoder User
userDecoder =
  decode User
    |> required "id" int
    |> required "email" string
    |> optional "name" string "(fallback if name not provided)"
    |> hardcoded 1.0

In this example:

  • decode is a synonym for succeed (it just reads better here)
  • required "id" int is similar to ("id" := int)
  • optional is like required, but if the field is not present, decoding does not fail; instead it succeeds with the provided fallback value.
  • hardcoded does not look at the provided JSON, and instead always decodes to the same value.

You could use this decoder as follows:

Json.Decode.decodeString
  userDecoder
  """
    {"id": 123, "email": "sam@example.com", "name": "Sam Sample"}
  """

The result would be:

{ id = 123
, email = "sam@example.com"
, name = "Sam Sample"
, percentExcited = 1.0
}

Alternatively, you could use it like so:

Json.Decode.decodeString
  userDecoder
  """
    {"id": 123, "email": "sam@example.com", "percentExcited": "(hardcoded)"}
  """

In this case, the result would be:

{ id = 123
, email = "sam@example.com"
, name = "(fallback if name not present)"
, percentExcited = 1.0
}

[NoRedInk][team] [team]: http://noredink.com/about/team

About

A pipeline-friendly library for building decoders.

http://package.elm-lang.org/packages/NoRedInk/elm-decode-pipeline/latest

License:BSD 3-Clause "New" or "Revised" License


Languages

Language:Elm 100.0%