= The `JSONUtil` structure
:Author: John Reppy
:Date: {release-date}
:stem: latexmath
:source-highlighter: pygments
:VERSION: {smlnj-version}

some overview

== Synopsis

[source,sml]
------------
structure JSONUtil
------------

== Interface

[source,sml]
------------
exception NotBool of JSON.value
exception NotInt of JSON.value
exception NotNumber of JSON.value
exception NotString of JSON.value

exception NotObject of JSON.value

exception FieldNotFound of JSON.value * string

exception NotArray of JSON.value

exception ArrayBounds of JSON.value * int

val exnMessage : exn -> string

val asBool : JSON.value -> bool
val asInt : JSON.value -> Int.int
val asIntInf : JSON.value -> IntInf.int
val asNumber : JSON.value -> Real.real
val asString : JSON.value -> string

val findField : JSON.value -> string -> JSON.value option

val lookupField : JSON.value -> string -> JSON.value

val asArray : JSON.value -> JSON.value vector

val arrayMap : (JSON.value -> 'a) -> JSON.value -> 'a list

datatype edge = SUB of int | SEL of string

type path = edge list

val get : JSON.value * path -> JSON.value

val replace : JSON.value * path * JSON.value -> JSON.value

val insert : JSON.value * path * string * JSON.value -> JSON.value

val append : JSON.value * path * JSON.value list -> JSON.value
------------

== Description

`[.kw]#exception# NotBool [.kw]#of# JSON.value`::
  [[exn:NotBool]]
  raised by the xref:val:asBool[`asBool`] function when the argument
  is not a *JSON* boolean.

`[.kw]#exception# NotInt [.kw]#of# JSON.value`::
  [[exn:NotInt]]
  raised by the xref:val:asInt[`asInt`] and xref:val:asIntInf[`asIntInf`]
  functions when the argument is not a *JSON* integer number.

`[.kw]#exception# NotNumber [.kw]#of# JSON.value`::
  [[exn:NotNumber]]
  raised by the xref:val:asNumber[`asNumber`] function when the argument
  is not a *JSON* number.

`[.kw]#exception# NotString [.kw]#of# JSON.value`::
  [[exn:NotString]]
  raised by the xref:val:asString[`asString`] function when the argument
  is not a *JSON* string.

`[.kw]#exception# NotObject [.kw]#of# JSON.value`::
  [[exn:NotObject]]
  raised by the xref:val:findField[`findField`] and
  xref:val:lookupField[`lookupField`] functions when the
  argument is not a *JSON* object.

`[.kw]#exception# FieldNotFound [.kw]#of# JSON.value * string`::
  [[exn:FieldNotFound]]
  This exception is raised when the given field is not found in an object.

`[.kw]#exception# NotArray [.kw]#of# JSON.value`::
  [[exn:NotArray]]
  This exception is raised when trying to process a non-array value as an array.

`[.kw]#exception# ArrayBounds [.kw]#of# JSON.value * int`::
  [[exn:ArrayBounds]]
  This exception is raised when access to an array value is out of bounds.

`[.kw]#val# exnMessage : exn -> string`::
  `exnMessage exn` returns an error-message string for the exception value
  `exn`.  This function produces specialized messages for the exceptions defined
  in the `JSONUtil` structure and falls back to the
  {sml-basis-url}/general.html#SIG:GENERAL.exnMessage:VAL[General.exnMessage]
  function for other exceptions.

`[.kw]#val# asBool : JSON.value -> bool`::
  [[val:asBool]]
  `asBool (JSON.BOOL b)` returns the value `b`.  This function raises
  the xref:exn:NotBool[`NotBool`] exception if the value is not a
  *JSON* boolean value.

`[.kw]#val# asInt : JSON.value -> int`::
  [[val:asInt]]
  `asInt (JSON.INT n)` returns the value `n` converted to `int`.
  This function raises the xref:exn:NotInt[`NotInt`] exception if the
  value is not a *JSON* integer value.  It may also raise the
  {sml-basis-url}/general.html#SIG:GENERAL.Overflow:EXN[`Overflow`]
  exception if `n` is too large for the default `int` type.

`[.kw]#val# asIntInf : JSON.value -> IntInf.int`::
  [[val:asIntInf]]
  `asIntInf (JSON.INT n)` returns the value `n`.
  This function raises the xref:exn:NotInt[`NotInt`] exception if the
  value is not a *JSON* integer value.

`[.kw]#val# asNumber : JSON.value -> Real.real`::
  [[val:asNumber]]
  `asNumber jv` converts the *JSON* number `jv` to an SML `real` value.
  The `jv` argument can either have the form `JSON.INT n`, in which case
  `n` is converted to the `real` type and returned, or `JSON.FLOAT f`,
  in which case `f` is returned; otherwise, the
  xref:exn:NotNumber[`NotNumber`] exception is raised.

`[.kw]#val# asString : JSON.value -> string`::
  [[val:asString]]
  `asBool (JSON.STRING s)` returns the value `s`.  This function raises
  the xref:exn:NotString[`NotString`] exception if the value is not a
  *JSON* string value.

`[.kw]#val# findField : JSON.value -> string -> JSON.value option`::
  [[val:findField]]
  `findField (JSON.OBJECT flds) key` returns `SOME jv` when the
  list of fields `flds` contains `(key, jv)` and `NONE` otherwise.
  If `findField` is called on a value that is not a *JSON* object,
  then it raises the xref:exn:NotObject[`NotObject`] exception.

`[.kw]#val# lookupField : JSON.value -> string -> JSON.value`::
  [[val:lookupField]]
  `lookupField (JSON.OBJECT flds) key` returns `jv` when the
  list of fields `flds` contains `(key, jv)` and raises the
  xref:exn:FieldNotFound[`FieldNotFound`] exception otherwise.
  If `lookupField` is called on a value that is not a *JSON* object,
  then it raises the xref:exn:NotObject[`NotObject`] exception.

  (* convert a JSON array to an SML vector *)
`[.kw]#val# asArray : JSON.value -> JSON.value vector`::
  [[val:asArray]]
  `asArray jv` converts the *JSON* array value `jv` to an *SML*
  vector value.  It raises the xref:exn:NotArray[`NotArray`] exception
  when `jv` is not a *JSON* array.

`[.kw]#val# arrayMap : (JSON.value -> 'a) -> JSON.value -> 'a list`::
  [[val:arrayMap]]
  map a conversion function over a JSON array to produce a list; this function
  raises the xref:exn:NotArray[`NotArray`] exception if the second argument
  is not an array.

`[.kw]#datatype# edge = ...`::
  specifies an edge of a path into a *JSON* value.
  The constructors have the following meaning:
+
--
    `SUB [.kw]#of# int`::
	`SUB i` specifies the `i`th element of a *JSON* array.
    `SEL [.kw]#of# string`::
	`SEL key` specifies the value labeled by `key` in a *JSON* object.
--

`[.kw]#type# path = edge list`::
  specifies a path into a *JSON* value.

`[.kw]#val# get : JSON.value * path \-> JSON.value`::
  [[val:get]]
  `get (jv, path)` returns the component of `jv` named by `path`.  It raises
  one of the xref:exn:NotObject[`NotObject`], xref:exn:NotArray[`NotArray`],
  or xref:exn:FieldNotFound[`FieldNotFound`] exceptions if there is an
  inconsistency between the path and the structure of `jv`.

== See Also

xref:str-JSON.adoc[`JSON`],
xref:json-lib.adoc[__The JSON Library__]
