From aff918c47247c30fae2755fe23501409bbc7d7ea Mon Sep 17 00:00:00 2001 From: Simmo Saan Date: Sun, 17 Jul 2022 16:23:43 +0300 Subject: [PATCH 1/5] Document Json_error --- lib/common.mli | 2 ++ lib/read.mli | 23 ++++++++++++----------- lib/write.mli | 17 +++++++++-------- lib/write2.mli | 3 +++ 4 files changed, 26 insertions(+), 19 deletions(-) diff --git a/lib/common.mli b/lib/common.mli index 28e90aec..aeb30a49 100644 --- a/lib/common.mli +++ b/lib/common.mli @@ -1,8 +1,10 @@ val version : string exception Json_error of string +(** Exception (usually) describing a parsing failure. *) val json_error : string -> 'a +(** @raise Json_error *) type lexer_state = { buf : Buffer.t; diff --git a/lib/read.mli b/lib/read.mli index 7fca7cd4..78376a9a 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. *) + 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. *) + See [to_string] for the role of the optional [std] argument and raised exceptions. *) (** {2 JSON readers} *) @@ -22,6 +22,7 @@ val from_string : @param fname data file name to be used in error messages. It does not have to be a real file. @param lnum number of the first line of input. Default is 1. + @raise Json_error if parsing fails. *) val from_channel : @@ -30,7 +31,7 @@ val from_channel : ?lnum:int -> in_channel -> t (** Read a JSON value from a channel. - See [from_string] for the meaning of the optional arguments. *) + See [from_string] for the meaning of the optional arguments and raised exceptions. *) val from_file : ?buf:Buffer.t -> @@ -38,7 +39,7 @@ val from_file : ?lnum:int -> string -> t (** Read a JSON value from a file. - See [from_string] for the meaning of the optional arguments. *) + See [from_string] for the meaning of the optional arguments and raised exceptions. *) type lexer_state = Lexer_state.t = { @@ -65,7 +66,7 @@ val from_lexbuf : 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. + 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 @@ -78,7 +79,7 @@ val seq_from_string : 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. *) + See [from_string] for the meaning of the optional arguments and raised exceptions. *) val seq_from_channel : ?buf:Buffer.t -> @@ -94,7 +95,7 @@ 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. *) + See [from_string] for the meaning of the other optional arguments and other raised exceptions. *) val seq_from_file : ?buf:Buffer.t -> @@ -104,7 +105,7 @@ val seq_from_file : (** 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. *) + See [from_string] for the meaning of the optional arguments and raised exceptions. *) val seq_from_lexbuf : lexer_state -> @@ -117,7 +118,7 @@ val seq_from_lexbuf : is raised, [exn] being the parsing exception and [fin_exn] the finalizer one. See [seq_from_channel] for the meaning of the optional [fin] - argument. *) + argument and other raised exceptions. *) type json_line = [ `Json of t | `Exn of exn ] @@ -135,7 +136,7 @@ val lineseq_from_channel : See [seq_from_channel] for the meaning of the optional [fin] argument. - See [from_string] for the meaning of the other optional arguments. *) + See [from_string] for the meaning of the other optional arguments and returned exceptions. *) val lineseq_from_file : ?buf:Buffer.t -> @@ -148,7 +149,7 @@ val lineseq_from_file : See [seq_from_channel] for the meaning of the optional [fin] argument. - See [from_string] for the meaning of the other optional arguments. *) + See [from_string] for the meaning of the other optional arguments and returned exceptions. *) val read_t : lexer_state -> Lexing.lexbuf -> t (** Read a JSON value from the given lexer_state and lexing buffer and return it. diff --git a/lib/write.mli b/lib/write.mli index 03e1e705..f6d3436c 100644 --- a/lib/write.mli +++ b/lib/write.mli @@ -18,6 +18,7 @@ val to_string : refuse to print NaN and infinities, require the root node to be either an object or an array. Default is [false]. + @raise Json_error if [float] value is not allowed in standard JSON. *) val to_channel : @@ -29,7 +30,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. *) + See [to_string] for the role of the optional arguments and raised exceptions. *) val to_output : ?buf:Buffer.t -> @@ -39,7 +40,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. *) + See [to_string] for the role of the optional arguments and raised exceptions. *) val to_file : ?len:int -> @@ -47,7 +48,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. + 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 +57,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. *) + See [to_string] for the role of the optional argument and raised exceptions. *) val seq_to_string : ?buf:Buffer.t -> @@ -67,7 +68,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. *) + See [to_string] for the role of the optional arguments and raised exceptions. *) val seq_to_channel : ?buf:Buffer.t -> @@ -78,7 +79,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. *) + See [to_channel] for the role of the optional arguments and raised exceptions. *) val seq_to_file : ?len:int -> @@ -88,7 +89,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. *) + See [to_string] for the role of the optional arguments and raised exceptions. *) val seq_to_buffer : ?suf:string -> @@ -98,7 +99,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. *) + 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 6efdc448..8097f5bc 100644 --- a/lib/write2.mli +++ b/lib/write2.mli @@ -3,15 +3,18 @@ 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. + @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. *) 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. *) From 373a6836b662391a8f11d705823f1b950123ce13 Mon Sep 17 00:00:00 2001 From: Simmo Saan Date: Sun, 17 Jul 2022 16:40:36 +0300 Subject: [PATCH 2/5] Expand Util exception documentation --- lib/util.mli | 67 ++++++++++++++++++++++++++++++++-------------------- 1 file changed, 41 insertions(+), 26 deletions(-) diff --git a/lib/util.mli b/lib/util.mli index ab6e88b9..b5fe3ed9 100644 --- a/lib/util.mli +++ b/lib/util.mli @@ -69,84 +69,99 @@ exception Undefined of string * t of bounds. *) val keys : t -> string list - (** Returns all the key names in the given JSON object *) + (** Returns all the key names in the given JSON object. + @raise Type_error if argument is not a JSON object. *) val values : t -> t list - (** Return all the value in the given JSON object *) + (** Return all the value in the given JSON object. + @raise Type_error if argument is not a JSON object. *) val combine : t -> t -> t - (** Combine two JSON Objects together *) + (** Combine two JSON objects together. + @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]. + @raise Type_error if [obj] is not a JSON object. *) val index : int -> t -> t (** [index i arr] returns the value at index [i] in the JSON array [arr]. Negative indices count from the end of the list (so -1 is the last - element). *) + element). + @raise Type_error if [arr] is not a JSON array. + @raise Undefined if index is out of bounds. *) val map : (t -> t) -> t -> t (** [map f arr] calls the function [f] on each element of the JSON array - [arr], and returns a JSON array containing the results. *) + [arr], and returns a JSON array containing the results. + @raise Type_error if [arr] is not an JSON array. *) val to_assoc : t -> (string * t) list - (** Extract the items of a JSON object or raise [Type_error]. *) + (** Extract the items of a JSON object. + @raise Type_error if argument is not a JSON object. *) val to_option : (t -> 'a) -> t -> 'a option (** Return [None] if the JSON value is null or map the JSON value to [Some] value using the provided function. *) val to_bool : t -> bool - (** Extract a boolean value or raise [Type_error]. *) + (** Extract a boolean value. + @raise Type_error if argument is not a JSON boolean. *) val to_bool_option : t -> bool option (** Extract [Some] boolean value, - return [None] if the value is null, - or raise [Type_error] otherwise. *) + return [None] if the value is null. + @raise Type_error if argument is neither. *) val to_number : t -> float - (** Extract a number or raise [Type_error]. *) + (** Extract a number. + @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, - or raise [Type_error] otherwise. *) + return [None] if the value is null. + @raise Type_error if argument is neither. *) val to_float : t -> float - (** Extract a float value or raise [Type_error]. - [to_number] is generally preferred as it also works with int literals. *) + (** Extract a float value. + [to_number] is generally preferred as it also works with int literals. + @raise Type_error if argument is not a JSON float. *) val to_float_option : t -> float option (** Extract [Some] float value, - return [None] if the value is null, - or raise [Type_error] otherwise. + return [None] if the value is null. [to_number_option] is generally preferred as it also works - with int literals. *) + with int literals. + @raise Type_error if argument is neither. *) val to_int : t -> int - (** Extract an int from a JSON int or raise [Type_error]. *) + (** Extract an int from a JSON int. + @raise Type_error if argument is not a JSON int. *) val to_int_option : t -> int option (** Extract [Some] int from a JSON int, - return [None] if the value is null, - or raise [Type_error] otherwise. *) + return [None] if the value is null. + @raise Type_error if argument is neither. *) val to_list : t -> t list - (** Extract a list from JSON array or raise [Type_error]. *) + (** Extract a list from JSON array. + @raise Type_error if argument is not a JSON array. *) val to_string : t -> string - (** Extract a string from a JSON string or raise [Type_error]. *) + (** Extract a string from a JSON string. + @raise Type_error if argument is not a JSON string. *) val to_string_option : t -> string option (** Extract [Some] string from a JSON string, - return [None] if the value is null, - or raise [Type_error] otherwise. *) + return [None] if the value is null. + @raise Type_error if argument is neither. *) val convert_each : (t -> 'a) -> t -> 'a list (** The conversion functions above cannot be used with [map], because they do not return JSON values. This convenience function [convert_each to_f arr] - is equivalent to [List.map to_f (to_list arr)]. *) + is equivalent to [List.map to_f (to_list arr)]. + @raise Type_error if [arr] is not a JSON array. *) (** {3 Exception-free filters} *) From e39d3a10a6abef805fb3eeaf89709bc7f9fe4d6b Mon Sep 17 00:00:00 2001 From: Simmo Saan Date: Sun, 17 Jul 2022 16:54:57 +0300 Subject: [PATCH 3/5] Add usage comments to write_float_fast and write_float_prec --- lib/write.ml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/write.ml b/lib/write.ml index 007e4e89..37765e75 100644 --- a/lib/write.ml +++ b/lib/write.ml @@ -121,7 +121,7 @@ let float_needs_period s = The _fast version is faster but often produces unnecessarily long numbers. *) -let write_float_fast ob x = +let write_float_fast ob x = (* unused *) match classify_float x with FP_nan -> Buffer.add_string ob "NaN" @@ -175,7 +175,7 @@ let write_normal_float_prec significant_figures ob x = if float_needs_period s then Buffer.add_string ob ".0" -let write_float_prec significant_figures ob x = +let write_float_prec significant_figures ob x = (* used by atdgen *) match classify_float x with FP_nan -> Buffer.add_string ob "NaN" @@ -190,7 +190,7 @@ let json_string_of_float x = Buffer.contents ob -let write_std_float_fast ob x = +let write_std_float_fast ob x = (* unused *) match classify_float x with FP_nan -> json_error "NaN value not allowed in standard JSON" @@ -226,7 +226,7 @@ let write_std_float ob x = if float_needs_period s then Buffer.add_string ob ".0" -let write_std_float_prec significant_figures ob x = +let write_std_float_prec significant_figures ob x = (* used by atdgen *) match classify_float x with FP_nan -> json_error "NaN value not allowed in standard JSON" From a08f7458db40a16dad2071ef105b2ef64bba79ea Mon Sep 17 00:00:00 2001 From: Simmo Saan Date: Mon, 18 Jul 2022 14:34:57 +0300 Subject: [PATCH 4/5] Update comments based on review (PR #148) --- lib/common.mli | 4 +++- lib/read.mli | 4 ++-- lib/write.ml | 12 ++++++++---- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/lib/common.mli b/lib/common.mli index aeb30a49..379ab025 100644 --- a/lib/common.mli +++ b/lib/common.mli @@ -1,7 +1,9 @@ val version : string exception Json_error of string -(** Exception (usually) describing a parsing failure. *) +(** Exception used: + - in JSON readers, if parsing fails; + - in JSON writers and pretty printing, if [float] value is not allowed in standard JSON. *) val json_error : string -> 'a (** @raise Json_error *) diff --git a/lib/read.mli b/lib/read.mli index 78376a9a..b2388b70 100644 --- a/lib/read.mli +++ b/lib/read.mli @@ -136,7 +136,7 @@ val lineseq_from_channel : See [seq_from_channel] for the meaning of the optional [fin] argument. - See [from_string] for the meaning of the other optional arguments and returned exceptions. *) + See [from_string] for the meaning of the other optional arguments and raised exceptions. *) val lineseq_from_file : ?buf:Buffer.t -> @@ -149,7 +149,7 @@ val lineseq_from_file : See [seq_from_channel] for the meaning of the optional [fin] argument. - See [from_string] for the meaning of the other optional arguments and returned 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. diff --git a/lib/write.ml b/lib/write.ml index 37765e75..12a7bb44 100644 --- a/lib/write.ml +++ b/lib/write.ml @@ -121,7 +121,8 @@ let float_needs_period s = The _fast version is faster but often produces unnecessarily long numbers. *) -let write_float_fast ob x = (* unused *) +(* unused *) +let write_float_fast ob x = match classify_float x with FP_nan -> Buffer.add_string ob "NaN" @@ -175,7 +176,8 @@ let write_normal_float_prec significant_figures ob x = if float_needs_period s then Buffer.add_string ob ".0" -let write_float_prec significant_figures ob x = (* used by atdgen *) +(* used by atdgen *) +let write_float_prec significant_figures ob x = match classify_float x with FP_nan -> Buffer.add_string ob "NaN" @@ -190,7 +192,8 @@ let json_string_of_float x = Buffer.contents ob -let write_std_float_fast ob x = (* unused *) +(* unused *) +let write_std_float_fast ob x = match classify_float x with FP_nan -> json_error "NaN value not allowed in standard JSON" @@ -226,7 +229,8 @@ let write_std_float ob x = if float_needs_period s then Buffer.add_string ob ".0" -let write_std_float_prec significant_figures ob x = (* used by atdgen *) +(* used by atdgen *) +let write_std_float_prec significant_figures ob x = match classify_float x with FP_nan -> json_error "NaN value not allowed in standard JSON" From 6aaecec86ed6511f906f1c6bbb2e906cba6be56c Mon Sep 17 00:00:00 2001 From: Simmo Saan Date: Mon, 18 Jul 2022 18:04:07 +0300 Subject: [PATCH 5/5] Add PR #148 to CHANGES --- CHANGES.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index a4d9175c..2adaa770 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,7 +1,9 @@ ## unreleased - + ### Added +- Expanded documentation of exceptions (@sim642, #148) + ### Removed ### Changed