APIJson

Json

Parsing and emitting JSON as typed values.

parse, read, stringify, and write cover whole documents through the Decode and Encode classes, which String, Int, Float, Char, Bool, (), List a, Maybe a, and Value implement, and which a type derives with deriving (Encode, Decode). Derived records are objects in declaration order, and decoding accepts their keys in any order and skips unknown ones; nullary constructors are strings such as "Red", and other constructors single-key objects such as {"RGB":[1,2,3]}; () and Nothing are null. Record fields can carry #[Json.Key "name"], #[Json.Default `7`], and #[Json.Skip] (see FieldOption).

Reading consumes tokens as needed, and a typed decoder builds no intermediate Value. Custom decoders and token-level parsing live in Json.Pull.

Error, Decode, Value, Number, and FieldOption are re-exported from Json.Pull and Json.Field. Decode is exposed without its method; a handwritten instance imports Decode(..) from Json.Pull. A duplicate declared key or a missing required field is a decoding error, and a nested Maybe cannot tell an outer Nothing from an inner one.

Error

type Error =    { message : String    , offset : Int    , line : Int    , column : Int    , path : String    }Source

Re-exported from Json.Pull.

A JSON failure and where it happened.

Fields

message

message : StringSource

Re-exported from Json.Pull.

What went wrong.

offset

offset : IntSource

Re-exported from Json.Pull.

The zero-based byte offset; -1 for a failure while emitting.

line

line : IntSource

Re-exported from Json.Pull.

The one-based line.

column

column : IntSource

Re-exported from Json.Pull.

The one-based column, counted in bytes.

path

path : StringSource

Re-exported from Json.Pull.

Where in the document, as slash-separated keys and indices, for a failure inside a decoded record, list, or value. An error found while scanning lookahead can come before its field or element is entered; typed arrays enter the index before scanning the element.

Instances:

Eq Error
Show Error

FieldOption

type FieldOption    = Key String    | Skip    | Default CodeSource

Re-exported from Json.Field.

An option on a record field, read by the JSON derivers. Each may occur once per field, emitted keys must be unique, and options anywhere but on a record field are rejected. Violations fail at compile time, at the attribute.

Constructors

Key

Key : String -> FieldOptionSource

Re-exported from Json.Field.

Use this wire key instead of the field name.

Default

Default : Code -> FieldOptionSource

Re-exported from Json.Field.

The value to use when decoding finds no key. The code is checked against the field’s type, keeps the scope it was written in, and runs only when the fallback is needed.

Skip

Skip : FieldOptionSource

Re-exported from Json.Field.

Omit the field when encoding and ignore it when decoding. It requires Default and cannot combine with Key.

Number

type NumberSource

Re-exported from Json.Pull.

A JSON number kept as its lexeme, so it round-trips without conversion. Json.number makes one and numberText reads it.

Value

type Value    = Null    | Boolean Bool    | Numeric Number    | Text String    | Array (List Value)    | Object (List (String, Value))Source

Re-exported from Json.Pull.

A generic JSON document tree. Object members keep their order.

Constructors

Null

Null : ValueSource

Re-exported from Json.Pull.

null.

Boolean

Boolean : Bool -> ValueSource

Re-exported from Json.Pull.

true or false.

Array

Array : List Value -> ValueSource

Re-exported from Json.Pull.

An array.

Numeric

Numeric : Number -> ValueSource

Re-exported from Json.Pull.

A number.

Text

Text : String -> ValueSource

Re-exported from Json.Pull.

A string.

Object

Object : List (String, Value) -> ValueSource

Re-exported from Json.Pull.

An object’s members, in order.

Instances:

Decode Value
Encode Value

Decode

class Decode aSource

Re-exported from Json.Pull.

Types that decode from JSON. Derive it, or write scanValue; a decoder written with Pull operations is scanValue cursor = Json.Pull.scanFromPull cursor { ... }.

Instances:

Decode ()
Decode Bool
Decode Char
Decode Float
Decode Int
Decode String
Decode Value
Decode a => Decode (List a)
Decode a => Decode (Maybe a)

Encode

class Encode aSource

Types that encode as JSON. A handwritten instance writes raw text with emit, or delegates to encodeValue for its parts.

Methods

encodeValue

encodeValue : Encode a => a ->{Fail Error, Emit} ()Source

Writes the value’s JSON. A nonfinite Float cannot be encoded.

Instances:

Encode ()
Encode Bool
Encode Char
Encode Float
Encode Int
Encode JsonCase
Encode JsonGroupFailure
Encode JsonLocation
Encode JsonReport
Encode JsonSummary
Encode String
Encode Value
Encode a => Encode (List a)
Encode a => Encode (Maybe a)

Emit

effect EmitSource

Writing raw JSON text, as encoders do. withWriter and withTextWriter handle it.

Operations

emit

emit : String ->{Emit} ()Source

Writes raw JSON text as it is.

array

array : Encode a => Stream a {Fail Error, Emit, e} ->{Fail Error, Emit, e} ()Source

Emits a JSON array of the stream’s elements, stepping the stream as it writes, so the array is never held in memory.

import Bytes
import Json
import Stream
import Tuple
import Writer

written = Writer.collecting { writer -> Json.withWriter writer { Json.array (Stream.fromList ["a", "b"]) } }

Tuple.second written == Bytes.fromString "[\"a\",\"b\"]"

number

number : String -> Result Error NumberSource

Validates a JSON number lexeme, keeping it exactly as written.

import Json
import Result exposing (Result(..))

Result.map Json.numberText (Json.number "1e3") == Ok "1e3"
Result.withDefault "" (Result.map Json.numberText (Json.number "01")) == ""

numberText

numberText : Number -> StringSource

Re-exported from Json.Pull.

The number’s lexeme as written.

object

object : List (String, () ->{Fail Error, Emit, e} ()) ->{Fail Error, Emit, e} ()Source

Emits a JSON object whose field values are emitted in order, each when it is reached, so an array field can stream before a later field is computed.

parse

parse : Decode a => Type a -> String -> Result Error aSource

Parses a whole document as the type the witness names, failing on trailing input. An Int must be a JSON integer in range, a Float a finite number, and a Char exactly one character.

import Json
import Result exposing (Result(..))

Json.parse @(List Int) "[1, 2, 3]" == Ok [1, 2, 3]
Json.parse @(Maybe String) "null" == Ok Nothing
Result.withDefault [] (Json.parse @(List Int) "[1,") == []

parseBytes

parseBytes : Decode a => Type a -> Bytes -> Result Error aSource

parse for UTF-8 bytes.

read

read : Decode a => Type a -> Reader e ->{e} Result Error aSource

parse from a byte reader, decoding UTF-8, which may be any source. It reads only what the document needs and has the reader’s effects.

readText

readText : Decode a => Type a -> Reader e ->{e} Result Error aSource

parse from a text reader, whose encoding the caller chose. Decoding errors become Error values.

stringify

stringify : Encode a => a -> Result Error StringSource

The value’s JSON as text, without whitespace.

import Json
import Result exposing (Result(..))

Json.stringify ["a", "b"] == Ok "[\"a\",\"b\"]"
Json.stringify (Just True) == Ok "true"
Json.stringify () == Ok "null"

withTextWriter

withTextWriter : Writer e -> (() ->{Fail Error, Emit, e} a) ->{e} Result Error aSource

withWriter over a text writer, whose encoding the caller chose; a character it cannot represent fails with an Error.

withWriter

withWriter : Writer e -> (() ->{Fail Error, Emit, e} a) ->{e} Result Error aSource

Runs action, writing what it emits to a byte writer as UTF-8. The action may perform the writer’s own effects between emits, so it can produce a document while it reads its source. Flushing is left to the writer’s owner.

import Bytes
import Json
import Tuple
import Writer

written = Writer.collecting { writer -> Json.withWriter writer { Json.object [("a", { Json.encodeValue "x" })] } }

Tuple.second written == Bytes.fromString "{\"a\":\"x\"}"

write

write : Encode a => Writer e -> a ->{e} Result Error ()Source

Writes a value’s JSON to a byte writer. The writer may already hold part of the output when encoding fails.

writeText

writeText : Encode a => Writer e -> a ->{e} Result Error ()Source

Writes a value’s JSON to a text writer.