jmpavlick/json-in-elm/2.0.0

Json.InElm

JSON Document and Property Types

A "JSON document", here, is described as:

  • A JSON object
  • A list of JSON objects or scalar properties

For convenience, even though it's not in the JSON spec, I have included ISO8601 timestamp values as a "JSON property type".

type alias Node =
{ value : JValue
, schema : Schema
}

A Node is a reprentation of part of a JSON document, along with everything that is inside of it, along with its "key path", which is its location within a JSON document.

This means that the output of the parser will always be a single Node; but depending on the input, that Node's JValue may have other Nodes inside of it.

type JValue
= JString String
| JInt Int
| JFloat Float
| JBool Bool
| JTime Posix
| JList (List Node)
| JObject (List ( String, Node ))
| JNull

A JValue represents a typed value within a JSON document.

type JProp
= PString
| PInt
| PFloat
| PBool
| PTime
| PNull

A JProp represents the type of a scalar property within a JSON document. These are regarded separately from the JValue type for a few important reasons:

  • Since this package is concerned with parsing an arbitrary JSON document and lifting it into a type that allows it to be used within an Elm program, this means that the JSON schema is derived ad-hoc from user input.
  • And so, an ad-hoc JSON schema cannot exist without values.
  • However, if we are going to to store references to locations within that ad-hoc JSON schema, we are likely doing so because we would like to retrieve some value at a given location from a JSON document that is different from the original input.

In order to create a distinction between "a parsed JSON value" and "a reference to a location within a JSON document", it must be the case that we have another way to represent the concept of "the expected type of a value at a location within a JSON document" that is separate from "a value at a location within a JSON document, from which the type is derived".

Creating a second type was the most straightforward way to implement this behavior.

= SObject
| SList

A JStructure represents a property that has a structural type (i.e., a list or an object) within a JSON document.

type alias Keypath =
Keypath

A Keypath is a data structure that stores the JSON path to a value of a given key.

Elements in a Keypath are either the name of a field, or the index of an array.

Use the functions in the Json.InElm.Keypath module to work with Keypath values.

type JTag
= Prop JProp
| Structure JStructure

A JTag is a "tag" that is used to store the type of a given property (scalar or structural) in a JSON document.

Json.InElm doesn't actually need to store this information in order to parse a JSON document, since it can be inferred directly from incoming data; however, it can be helpful to store this information for later retrieval and evaluation, so a type JTag that unions JProps and JStructures is provided.

type alias Schema =
{ keypath : Keypath
, tag : JTag
}

A Schema describes the type of, and path to, a given Node.

Parsing

parseValue : Value -> Node

Parse a Json.Decode.Value to a Node.

parseValueAt : Keypath -> Value -> Result Error Node

Parse a Json.Decode.Value to a Node, at a given KeyPath.

parseJsonString : String -> Result Error Node

Parse a raw JSON string to a Node.

toDecoder : Keypath -> Decoder Node

Create a decoder to a Node, given a Keypath.

Retrieving values from a JValue

toNodes : Node -> List Node

From a Node, get all possible Nodes.

toString : JValue -> Maybe String

Try to get a String from a JValue.

toInt : JValue -> Maybe Int

Try to get a Int from a JValue.

toFloat : JValue -> Maybe Float

Try to get a Float from a JValue.

toBool : JValue -> Maybe Bool

Try to get a Bool from a JValue.

toTime : JValue -> Maybe Posix

Try to get a Time from a JValue.

toList : JValue -> Maybe (List Node)

Try to get a List Node from a JValue.

toObject : JValue -> Maybe (List ( String, Node ))

Try to get a List (String, Node) from a JValue, where the String value is the name of the field in the object.

toNull : JValue -> Maybe ()

Try to see if a JValue contains a JSON null.

Viewing a Node

{ string : String -> Html msg
, int : Int -> Html msg
, float : Float -> Html msg
, bool : Bool -> Html msg
, time : Posix -> Html msg
, null : Html msg
, list : List (Html msg) -> Html msg
, object :
{ key : String
, value : Html msg
}
-> Html msg
, withKeypath : Maybe (String -> Html msg -> Html msg)
, withOnClick : Maybe (Node -> msg)
}
-> Node
-> Html msg

Combinator that allows you to build a view function that renders a Node; i.e., if you can provide all of the functions to destructure a Node, we can display it for you!