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

The `JSON_STREAM_OUTPUT` signature defines an interface for
stream-output of *JSON* values.

== Synopsis

[source,sml]
------------
signature JSON_STREAM_OUTPUT

structure JSONBufferPrinter : JSON_STREAM_OUTPUT
    where type outstream = CharBuffer.buf
structure JSONStreamPrinter : JSON_STREAM_OUTPUT
    where type outstream = outstream
------------

== Interface

[source,sml]
------------
type outstream

type printer

val new : outstream -> printer
val new' : {strm : outstream, pretty : bool} -> printer

val close : printer -> unit

val null : printer -> unit
val boolean : printer * bool -> unit
val integer : printer * IntInf.int -> unit
val int : printer * int -> unit
val float : printer * real -> unit
val string : printer * string -> unit
val beginObject : printer -> unit
val objectKey : printer * string -> unit
val endObject : printer -> unit
val beginArray : printer -> unit
val endArray : printer -> unit

val value : printer * JSON.value -> unit
------------

== Description

`[.kw]#type# outstream`::
  The type of the text consumer that the printer is layered on top of.

`[.kw]#type# printer`::
  The `printer` type tracks the current _state_ of the output so that it
  can correctly add punctuation and white space (when pretty printing).

`[.kw]#val# new : outstream \-> printer`::
  `new outS` creates a new printer from the output stream `outS`.
  The printer produces a _condensed_ format without newlines or
  indentation; use the ``new'`` function to create a pretty-printer
  for *JSON* output.

`[.kw]#val# new' : {strm : outstream, pretty : bool} \-> printer`::
  `new' {strm, pretty}` creates a new pretty-printing stream from the output
  stream `strm`, where the value of the `pretty` field controls whether
  the output is condensed (when `pretty` is `false`) or printed with
  new lines and indentation to improve readability (when `pretty` is `true`).

`[.kw]#val# close : printer \-> unit`::
  `close pr` closes the printer, but not the underlying output stream.
  Closing the printer while there is an open object or array results in
  the {sml-basis-url}/general.html#SIG:GENERAL.Fail:EXN[`Fail`]
  exception being raised.  Also, calling any of the below printing
  functions on a closed printer will result in the
  {sml-basis-url}/general.html#SIG:GENERAL.Fail:EXN[`Fail`]
  exception being raised.

`[.kw]#val# null : printer \-> unit`::
  `null pr` prints the *JSON* *null* value.  Raises the
  {sml-basis-url}/general.html#SIG:GENERAL.Fail:EXN[`Fail`]
  exception if the printer is closed.

`[.kw]#val# boolean : printer * bool \-> unit`::
  `boolean (pr, b)` prints the *JSON* boolean value `b`.  Raises the
  {sml-basis-url}/general.html#SIG:GENERAL.Fail:EXN[`Fail`]
  exception if the printer is closed.

`[.kw]#val# integer : printer * IntInf.int \-> unit`::
  `integer (pr, n)` prints the *JSON* number `n`.  Raises the
  {sml-basis-url}/general.html#SIG:GENERAL.Fail:EXN[`Fail`]
  exception if the printer is closed.

`[.kw]#val# int : printer * int \-> unit`::
  `int (pr, n)` prints the *JSON* number `n`.  Raises the
  {sml-basis-url}/general.html#SIG:GENERAL.Fail:EXN[`Fail`]
  exception if the printer is closed.  This function is a convenience
  for when one wants to print a default-int-type value without
  converting it to a `IntInf.int` first.

`[.kw]#val# float : printer * real \-> unit`::
  `float (pr, r)` prints the *JSON* floating-point number `r`.
  Raises the {sml-basis-url}/general.html#SIG:GENERAL.Fail:EXN[`Fail`]
  exception if the printer is closed.

`[.kw]#val# string : printer * string \-> unit`::
  `string (pr, s)` prints the *JSON* string `s`.  Raises the
  {sml-basis-url}/general.html#SIG:GENERAL.Fail:EXN[`Fail`]
  exception if the printer is closed.

`[.kw]#val# beginObject : printer \-> unit`::
  `beginArray pr` prints the opening "`{`" for a *JSON* object.
  Note that each call to `beginObject` should be matched by a call
  to `endObject`.  Raises the
  {sml-basis-url}/general.html#SIG:GENERAL.Fail:EXN[`Fail`]
  exception if the printer is closed.

`[.kw]#val# objectKey : printer * string \-> unit`::
  `objectKey (pr, key)` prints the *JSON* key-value `key` followed
  by a "`:`".  This function should be inside matched
  `beginObject`/`endObject` calls and should be followed by
  the printing of a *JSON* value.  Raises the
  {sml-basis-url}/general.html#SIG:GENERAL.Fail:EXN[`Fail`]
  exception if the printer is closed.

`[.kw]#val# endObject : printer \-> unit`::
  `endObject pr` prints the closing `}` for the currently open object.
  The {sml-basis-url}/general.html#SIG:GENERAL.Fail:EXN[`Fail`]
  exception is raised if the current context is not an open object,
  if a key has been printed without an associated value, or
  if the printer is closed.

`[.kw]#val# beginArray : printer \-> unit`::
  `beginArray pr` prints the opening "`[`" for a *JSON* array.
  Note that each call to `beginArray` should be matched by a call
  to `endArray`.  Raises the
  {sml-basis-url}/general.html#SIG:GENERAL.Fail:EXN[`Fail`]
  exception if the printer is closed.

`[.kw]#val# endArray : printer \-> unit`::
  `endArray pr` prints the closing `]` for the currently open array.
  The {sml-basis-url}/general.html#SIG:GENERAL.Fail:EXN[`Fail`]
  exception is raised if the current context is not an open array
  or if the printer is closed.

`[.kw]#val# value : printer * JSON.value \-> unit`::
  `value (pr, v)` embeds the *JSON* value `v` in the output.  It is
  equivalent to recursively traversing the *JSON* value while calling
  the appropriate output functions from above.

== See Also

xref:str-JSON.adoc[`JSON`],
xref:str-JSONBufferPrinter.adoc[`JSONBufferPrinter`],
xref:str-JSONPrinter.adoc[`JSONPrinter`],
xref:str-JSONStreamParser.adoc[`JSONStreamParser`],
xref:str-JSONStreamPrinter.adoc[`JSONStreamPrinter`],
xref:json-lib.adoc[__The JSON Library__]
