diff --git a/README.md b/README.md index de62ad8..dd0f613 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,19 @@ -Yojson: JSON library for OCaml -============================== +Yojson: JSON libraries for OCaml +================================ [![Build Status](https://img.shields.io/endpoint?url=https%3A%2F%2Focaml.ci.dev%2Fbadge%2Focaml-community%2Fyojson%2Fmaster&logo=ocaml)](https://ocaml.ci.dev/github/ocaml-community/yojson) -This library parses JSON data into a nested OCaml tree data structure. +The Yojson libraries parse JSON and JSON5 data into a nested OCaml tree data +structures. Library documentation --------------------- -Currently at https://ocaml-community.github.io/yojson/ +The documentation of both +[Yojson](https://ocaml.org/p/yojson/latest/doc/index.html) and +[Yojson-five](https://ocaml.org/p/yojson-five/latest/doc/index.html) can be +found on [OCaml.org](https://ocaml.org). Examples @@ -30,7 +34,7 @@ let json = Yojson.Safe.from_string json_string let () = Format.printf "Parsed to %a" Yojson.Safe.pp json ``` -The `examples` directory contains more. +The `examples` directory contains more examples. Related tooling --------------- diff --git a/doc/index.mld b/doc/index.mld index 8001c33..361446c 100644 --- a/doc/index.mld +++ b/doc/index.mld @@ -7,9 +7,6 @@ The design goals of Yojson are the following: to read and write directly without going through a generic JSON tree, for efficiency purposes. - Distinguishing between ints and floats. -- Providing optional extensions of the JSON syntax. -These extensions include comments, arbitrary strings, -optional quotes around field names. See {{:http://json.org}JSON specification}. @@ -18,4 +15,3 @@ Author: Martin Jambon {1 Entry point} The entry point of this library is the module {!yojson}. - diff --git a/lib/common.mli b/lib/common.mli index 8e6aa7a..6bcb25a 100644 --- a/lib/common.mli +++ b/lib/common.mli @@ -29,7 +29,7 @@ end val init_lexer : ?buf:Buffer.t -> ?fname:string -> ?lnum:int -> unit -> lexer_state -(** Create a fresh lexer_state record. *) +(** Create a fresh {!lexer_state} record. *) (**/**) (* begin undocumented section *) diff --git a/lib/json5/yojson_five.mli b/lib/json5/yojson_five.mli index 8e069cd..71e4e85 100644 --- a/lib/json5/yojson_five.mli +++ b/lib/json5/yojson_five.mli @@ -1,71 +1,157 @@ +(** + This module contains the parsers and pretty printers for JSON 5, as defined + by the JSON 5 spec. +*) + module Safe : sig + (** + This module is the equivalent of {!Yojson.Safe}, thus parses to the same data + structure, except it does so by the JSON 5 parsing rules. + + This module is recommended for intensive use or OCaml-friendly use of + JSON. + *) + type t = Yojson.Safe.t + (** This type represents the result of reading JSON5 data. All the utility + functions of {!Yojson.Safe.Util} can be used with values of this type. *) val from_string : ?fname:string -> ?lnum:int -> string -> (t, string) result + (** Attempts to parse JSON5 values from the supplied string. + @param fname The file name to use in error messages + @param lnum The line number to use in error messages *) val from_channel : ?fname:string -> ?lnum:int -> in_channel -> (t, string) result + (** Like {!from_string} but reads the data from an [in_channel]. *) val from_file : ?fname:string -> ?lnum:int -> string -> (t, string) result + (** Like {!from_string} but the parameter is the file name of the file + to open and read. *) val to_string : ?buf:Buffer.t -> ?len:int -> ?suf:string -> ?std:bool -> t -> string + (** Converts the parsed data into a string representation. + @param buf allows to reuse an existing buffer created with + [Buffer.create]. The buffer is cleared of all contents before starting + and right before returning. + @param len initial length of the output buffer. + @param suf appended to the output as suffix, defaults to the empty + string + @param std Unused, retained to match the signature of + {!Yojson.Safe.to_string}. + *) val to_channel : - ?buf:Stdlib.Buffer.t -> + ?buf:Buffer.t -> ?len:int -> ?suf:string -> ?std:bool -> - Stdlib.out_channel -> + out_channel -> t -> unit + (** Like {!to_string} but will write into the specified [out_channel]. *) val to_output : - ?buf:Stdlib.Buffer.t -> + ?buf:Buffer.t -> ?len:int -> ?suf:string -> ?std:bool -> < output : string -> int -> int -> int > -> t -> unit + (** Like {!to_string} but will write into an object with a method [output] of + type [string -> int -> int -> int]. The first argument is the string + representation of the JSON data, the second one is the start value + (always 0), the second is the length of the data and the return value + has to be an int but its value can be arbitrary as it is never used. *) val to_file : ?len:int -> ?std:bool -> ?suf:string -> string -> t -> unit + (** Like {!to_string} but will open and write to the file specified. *) + val pp : Format.formatter -> t -> unit + (** Pretty-printer for values of type {!t}. *) + val equal : t -> t -> bool + (** [equal a b] is the monomorphic equality. + Determines whether two JSON values are considered equal. In the case of + JSON objects, the order of the keys does not matter, except for + duplicate keys which will be considered equal as long as they are in the + same input order. + *) end module Basic : sig + (** + The equivalent of {!Yojson.Basic} but for reading and writing JSON5 data. + + The main advantage of this module is its simplicity. + *) + type t = Yojson.Basic.t + (** This type represents JSON5 data in the {!Yojson.Basic} format. *) val from_string : ?fname:string -> ?lnum:int -> string -> (t, string) result + (** Attempts to parse JSON5 values from the supplied string. + @param fname The file name to use in error messages + @param lnum The line number to use in error messages *) val from_channel : ?fname:string -> ?lnum:int -> in_channel -> (t, string) result + (** Like {!from_string} but reads the data from an [in_channel]. *) val from_file : ?fname:string -> ?lnum:int -> string -> (t, string) result + (** Like {!from_string} but the parameter is the file name of the file + to open and read. *) val to_string : ?buf:Buffer.t -> ?len:int -> ?suf:string -> ?std:bool -> t -> string + (** Converts the parsed data into a string representation. + @param buf allows to reuse an existing buffer created with + [Buffer.create]. The buffer is cleared of all contents before starting + and right before returning. + @param len initial length of the output buffer. + @param suf appended to the output as suffix, defaults to the empty + string + @param std Unused, retained to match the signature of + {!Yojson.Basic.to_string}. + *) val to_channel : - ?buf:Stdlib.Buffer.t -> + ?buf:Buffer.t -> ?len:int -> ?suf:string -> ?std:bool -> Stdlib.out_channel -> t -> unit + (** Like {!to_string} but will write into the specified [out_channel]. *) val to_output : - ?buf:Stdlib.Buffer.t -> + ?buf:Buffer.t -> ?len:int -> ?suf:string -> ?std:bool -> < output : string -> int -> int -> int > -> t -> unit + (** Like {!to_string} but will write into an object with a method [output] of + type [string -> int -> int -> int]. The first argument is the string + representation of the JSON data, the second one is the start value + (always 0), the second is the length of the data and the return value + has to be an int but its value can be arbitrary as it is never used. *) val to_file : ?len:int -> ?std:bool -> ?suf:string -> string -> t -> unit + (** Like {!to_string} but will open and write to the file specified. *) + val pp : Format.formatter -> t -> unit + (** Pretty-printer for values of type {!t}. *) + val equal : t -> t -> bool + (** [equal a b] is the monomorphic equality. + Determines whether two JSON values are considered equal. In the case of + JSON objects, the order of the keys does not matter, except for + duplicate keys which will be considered equal as long as they are in the + same input order. + *) end diff --git a/lib/monomorphic.mli b/lib/monomorphic.mli index 1bb233d..90f49ba 100644 --- a/lib/monomorphic.mli +++ b/lib/monomorphic.mli @@ -1,8 +1,8 @@ val pp : Format.formatter -> t -> unit -(** Pretty printer, useful for debugging *) +(** Pretty printer, useful for debugging. *) val show : t -> string -(** Convert value to string, useful for debugging *) +(** Convert value to string, useful for debugging. *) val equal : t -> t -> bool (** [equal a b] is the monomorphic equality. diff --git a/lib/read.mli b/lib/read.mli index f1ad820..ff6d44b 100644 --- a/lib/read.mli +++ b/lib/read.mli @@ -1,10 +1,10 @@ val prettify : ?std:bool -> string -> string (** Combined parser and pretty-printer. - See [to_string] for the role of the optional [std] argument and raised exceptions. *) + See {!to_string} for the role of the optional [std] argument and raised exceptions. *) val compact : ?std:bool -> string -> string (** Combined parser and printer. - See [to_string] for the role of the optional [std] argument and raised exceptions. *) + See {!to_string} for the role of the optional [std] argument and raised exceptions. *) (** {2 JSON readers} *) @@ -24,11 +24,11 @@ val from_string : ?buf:Buffer.t -> ?fname:string -> ?lnum:int -> string -> t val from_channel : ?buf:Buffer.t -> ?fname:string -> ?lnum:int -> in_channel -> t (** Read a JSON value from a channel. - See [from_string] for the meaning of the optional arguments and raised exceptions. *) + See {!from_string} for the meaning of the optional arguments and raised exceptions. *) val from_file : ?buf:Buffer.t -> ?fname:string -> ?lnum:int -> string -> t (** Read a JSON value from a file. - See [from_string] for the meaning of the optional arguments and raised exceptions. *) + See {!from_string} for the meaning of the optional arguments and raised exceptions. *) type lexer_state = Common.Lexer_state.t = { buf : Buffer.t; @@ -37,18 +37,19 @@ type lexer_state = Common.Lexer_state.t = { mutable fname : string option; } (** This alias is provided for backward compatibility. - New code should refer to {!Yojson.lexer_state} directly. - *) + + @deprecated Use {!Yojson.Lexer_state} instead. *) val init_lexer : ?buf:Buffer.t -> ?fname:string -> ?lnum:int -> unit -> lexer_state (** This alias is provided for backward compatibility. - New code should use {!Yojson.init_lexer} directly. *) + + @deprecated Use {!Yojson.init_lexer} instead. *) val from_lexbuf : lexer_state -> ?stream:bool -> Lexing.lexbuf -> t (** Read a JSON value from a lexbuf. - A valid initial [lexer_state] can be created with [init_lexer]. - See [from_string] for the meaning of the optional arguments and raised exceptions. + A valid initial {!lexer_state} can be created with {!Yojson.init_lexer}. + See {!from_string} for the meaning of the optional arguments and raised exceptions. @param stream indicates whether more data may follow. The default value is false and indicates that only JSON whitespace can be found between @@ -58,7 +59,7 @@ val seq_from_string : ?buf:Buffer.t -> ?fname:string -> ?lnum:int -> string -> t Seq.t (** Input a sequence of JSON values from a string. Whitespace between JSON values is fine but not required. - See [from_string] for the meaning of the optional arguments and raised exceptions. *) + See {!from_string} for the meaning of the optional arguments and raised exceptions. *) val seq_from_channel : ?buf:Buffer.t -> @@ -75,19 +76,19 @@ val seq_from_channel : @raise Finally When the parsing and the finalizer both raised, [Finally (exn, fin_exn)] is raised, [exn] being the parsing exception and [fin_exn] the finalizer one. - See [from_string] for the meaning of the other optional arguments and other raised exceptions. *) + See {!from_string} for the meaning of the other optional arguments and other raised exceptions. *) val seq_from_file : ?buf:Buffer.t -> ?fname:string -> ?lnum:int -> string -> t Seq.t (** Input a sequence of JSON values from a file. Whitespace between JSON values is fine but not required. - See [from_string] for the meaning of the optional arguments and raised exceptions. *) + See {!from_string} for the meaning of the optional arguments and raised exceptions. *) val seq_from_lexbuf : lexer_state -> ?fin:(unit -> unit) -> Lexing.lexbuf -> t Seq.t (** Input a sequence of JSON values from a lexbuf. - A valid initial [lexer_state] can be created with [init_lexer]. + A valid initial {!lexer_state} can be created with {!Yojson.init_lexer}. Whitespace between JSON values is fine but not required. @raise Finally When the parsing and the finalizer both raised, [Finally (exn, fin_exn)] is raised, [exn] being the parsing exception and [fin_exn] the finalizer one. @@ -109,9 +110,9 @@ val lineseq_from_channel : Exceptions raised when reading malformed lines are caught and represented using [`Exn]. - See [seq_from_channel] for the meaning of the optional [fin] + See {!seq_from_channel} for the meaning of the optional [fin] argument. - See [from_string] for the meaning of the other optional arguments and raised exceptions. *) + See {!from_string} for the meaning of the other optional arguments and raised exceptions. *) val lineseq_from_file : ?buf:Buffer.t -> ?fname:string -> ?lnum:int -> string -> json_line Seq.t @@ -119,12 +120,12 @@ val lineseq_from_file : Exceptions raised when reading malformed lines are caught and represented using [`Exn]. - See [seq_from_channel] for the meaning of the optional [fin] + See {!seq_from_channel} for the meaning of the optional [fin] argument. - See [from_string] for the meaning of the other optional arguments and raised exceptions. *) + See {!from_string} for the meaning of the other optional arguments and raised exceptions. *) val read_t : lexer_state -> Lexing.lexbuf -> t -(** Read a JSON value from the given lexer_state and lexing buffer and return it. +(** Read a JSON value from the given {!lexer_state} and lexing buffer and return it. Provided as a reader function for atdgen. *) diff --git a/lib/util.mli b/lib/util.mli index bfbf445..dcefee0 100644 --- a/lib/util.mli +++ b/lib/util.mli @@ -77,17 +77,20 @@ val values : t -> t list @raise Type_error if argument is not a JSON object. *) val combine : t -> t -> t -(** Combine two JSON objects together. +(** [combine a b] Will join two JSON objects together, the resulting object + contains the keys of [a] and then the keys of [b]. Duplication of keys + can occur. @raise Invalid_argument if either argument is not a JSON object. *) val member : string -> t -> t (** [member k obj] returns the value associated with the key [k] in the JSON - object [obj], or [`Null] if [k] is not present in [obj]. + object [obj], or [`Null] if [k] is not present in [obj]. To distinguish + between a key that doesn't exist and [`Null] use {!path}. @raise Type_error if [obj] is not a JSON object. *) val path : string list -> t -> t option -(* [path l obj] recurses the JSON object [obj] for each key in the path - [l] until the path is empty or there is no such key in the chain. *) +(** [path l obj] recurses the JSON object [obj] for each key in the path + [l] until the path is empty or there is no such key in the chain. *) val index : int -> t -> t (** [index i arr] returns the value at index [i] in the JSON array [arr]. @@ -119,12 +122,12 @@ val to_bool_option : t -> bool option @raise Type_error if argument is neither. *) val to_number : t -> float -(** Extract a number. +(** Extract a number. This works on both integers and floats. @raise Type_error if argument is not a JSON number. *) val to_number_option : t -> float option (** Extract [Some] number, - return [None] if the value is null. + return [None] if the value is [`Null]. @raise Type_error if argument is neither. *) val to_float : t -> float diff --git a/lib/write.mli b/lib/write.mli index 95e87f7..ebda5f2 100644 --- a/lib/write.mli +++ b/lib/write.mli @@ -29,7 +29,7 @@ val to_channel : (** Write a compact JSON value to a channel. Note: the [out_channel] is not flushed by this function. - See [to_string] for the role of the optional arguments and raised exceptions. *) + See {!to_string} for the role of the optional arguments and raised exceptions. *) val to_output : ?buf:Buffer.t -> @@ -39,7 +39,7 @@ val to_output : < output : string -> int -> int -> int; .. > -> t -> unit (** Write a compact JSON value to an OO channel. - See [to_string] for the role of the optional arguments and raised exceptions. *) + See {!to_string} for the role of the optional arguments and raised exceptions. *) val to_file : ?len:int -> @@ -47,7 +47,7 @@ val to_file : ?suf:string -> string -> t -> unit (** Write a compact JSON value to a file. - See [to_string] for the role of the optional arguments and raised exceptions. + See {!to_string} for the role of the optional arguments and raised exceptions. @param suf is a suffix appended to the output Newline by default for POSIX compliance. *) @@ -56,7 +56,7 @@ val to_buffer : ?std:bool -> Buffer.t -> t -> unit (** Write a compact JSON value to an existing buffer. - See [to_string] for the role of the optional argument and raised exceptions. *) + See {!to_string} for the role of the optional argument and raised exceptions. *) val seq_to_string : ?buf:Buffer.t -> @@ -67,7 +67,7 @@ val seq_to_string : (** Write a sequence of [suf]-suffixed compact one-line JSON values to a string. @param suf is the suffix ouf each value written. Newline by default. - See [to_string] for the role of the optional arguments and raised exceptions. *) + See {!to_string} for the role of the optional arguments and raised exceptions. *) val seq_to_channel : ?buf:Buffer.t -> @@ -78,7 +78,7 @@ val seq_to_channel : (** Write a sequence of [suf]-suffixed compact one-line JSON values to a channel. @param suf is the suffix of each value written. Newline by default. - See [to_channel] for the role of the optional arguments and raised exceptions. *) + See {!to_channel} for the role of the optional arguments and raised exceptions. *) val seq_to_file : ?len:int -> @@ -88,7 +88,7 @@ val seq_to_file : (** Write a sequence of [suf]-suffixed compact one-line JSON values to a file. @param suf is the suffix of each value written. Newline by default. - See [to_string] for the role of the optional arguments and raised exceptions. *) + See {!to_string} for the role of the optional arguments and raised exceptions. *) val seq_to_buffer : ?suf:string -> @@ -98,7 +98,7 @@ val seq_to_buffer : (** Write a sequence of [suf]-suffixed compact one-line JSON values to an existing buffer. @param suf is the suffix of each value written. Newline by default. - See [to_string] for the role of the optional arguments and raised exceptions. *) + See {!to_string} for the role of the optional arguments and raised exceptions. *) val write_t : Buffer.t -> t -> unit (** Write the given JSON value to the given buffer. diff --git a/lib/write2.mli b/lib/write2.mli index 551f25d..463c96e 100644 --- a/lib/write2.mli +++ b/lib/write2.mli @@ -2,19 +2,19 @@ val pretty_print : ?std:bool -> Format.formatter -> t -> unit (** Pretty-print into a {!Format.formatter}. - See [to_string] for the role of the optional [std] argument. + See {!to_string} for the role of the optional [std] argument. @raise Json_error if [float] value is not allowed in standard JSON. @since 1.3.1 *) val pretty_to_string : ?std:bool -> t -> string (** Pretty-print into a string. - See [to_string] for the role of the optional [std] argument. - See [pretty_print] for raised exceptions. + See {!to_string} for the role of the optional [std] argument. + See {!pretty_print} for raised exceptions. *) val pretty_to_channel : ?std:bool -> out_channel -> t -> unit (** Pretty-print to a channel. - See [to_string] for the role of the optional [std] argument. - See [pretty_print] for raised exceptions. + See {!to_string} for the role of the optional [std] argument. + See {!pretty_print} for raised exceptions. *)