diff --git a/CHANGES.md b/CHANGES.md index 3c041890..abbf7278 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -23,6 +23,10 @@ (@tmcgilchrist, #117) - Add a benchmark to judge the respective performance of providing a buffer vs letting Yojson create an internal (#134, @Leonidas-from-XIV) +- Add an optional `suf` keyword argument was added to functions that write + serialized JSON, thus allowing NDJSON output. Most functions default to not + adding any suffix except for `to_file` (#124) and functions writing sequences + of values where the default is `\n` (#135, @Lenoidas-from-XIV) ### Change diff --git a/lib/write.ml b/lib/write.ml index 45a2dcb0..007e4e89 100644 --- a/lib/write.ml +++ b/lib/write.ml @@ -417,14 +417,14 @@ and write_std_variant ob s o = #endif -let to_buffer ?(std = false) ob x = +let to_buffer ?(suf = "") ?(std = false) ob x = if std then write_std_json ob x else - write_json ob x - + write_json ob x; + Buffer.add_string ob suf -let to_string ?buf ?(len = 256) ?std x = +let to_string ?buf ?(len = 256) ?(suf = "") ?std x = let ob = match buf with None -> Buffer.create len @@ -432,46 +432,44 @@ let to_string ?buf ?(len = 256) ?std x = Buffer.clear ob; ob in - to_buffer ?std ob x; + to_buffer ~suf ?std ob x; let s = Buffer.contents ob in Buffer.clear ob; s -let to_channel ?buf ?(len=4096) ?std oc x = +let to_channel ?buf ?(len=4096) ?(suf = "") ?std oc x = let ob = match buf with None -> Buffer.create len | Some ob -> Buffer.clear ob; ob in - to_buffer ?std ob x; + to_buffer ~suf ?std ob x; Buffer.output_buffer oc ob; Buffer.clear ob -let to_output ?buf ?(len=4096) ?std out x = +let to_output ?buf ?(len=4096) ?(suf = "") ?std out x = let ob = match buf with None -> Buffer.create len | Some ob -> Buffer.clear ob; ob in - to_buffer ?std ob x; + to_buffer ~suf ?std ob x; out#output (Buffer.contents ob) 0 (Buffer.length ob); Buffer.clear ob -let to_file ?len ?std ?(newline = true) file x = +let to_file ?len ?std ?(suf = "\n") file x = let oc = open_out file in try - to_channel ?len ?std oc x; - if newline then - output_string oc "\n"; + to_channel ?len ~suf ?std oc x; close_out oc with e -> close_out_noerr oc; raise e -let seq_to_buffer ?std ob st = - Seq.iter (to_buffer ?std ob) st +let seq_to_buffer ?(suf = "\n") ?std ob st = + Seq.iter (to_buffer ~suf ?std ob) st -let seq_to_string ?buf ?(len = 256) ?std st = +let seq_to_string ?buf ?(len = 256) ?(suf = "\n") ?std st = let ob = match buf with None -> Buffer.create len @@ -479,27 +477,27 @@ let seq_to_string ?buf ?(len = 256) ?std st = Buffer.clear ob; ob in - seq_to_buffer ?std ob st; + seq_to_buffer ~suf ?std ob st; let s = Buffer.contents ob in Buffer.clear ob; s -let seq_to_channel ?buf ?(len=2096) ?std oc seq = +let seq_to_channel ?buf ?(len=2096) ?(suf = "\n") ?std oc seq = let ob = match buf with None -> Buffer.create len | Some ob -> Buffer.clear ob; ob in Seq.iter (fun json -> - to_buffer ?std ob json; + to_buffer ~suf ?std ob json; Buffer.output_buffer oc ob; Buffer.clear ob; ) seq -let seq_to_file ?len ?std file st = +let seq_to_file ?len ?(suf = "\n") ?std file st = let oc = open_out file in try - seq_to_channel ?len ?std oc st; + seq_to_channel ?len ~suf ?std oc st; close_out oc with e -> close_out_noerr oc; diff --git a/lib/write.mli b/lib/write.mli index 37ddf8ba..c36e0006 100644 --- a/lib/write.mli +++ b/lib/write.mli @@ -3,6 +3,7 @@ val to_string : ?buf:Buffer.t -> ?len:int -> + ?suf:string -> ?std:bool -> t -> string (** Write a compact JSON value to a string. @@ -10,6 +11,8 @@ val to_string : [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 a suffix, + defaults to empty string. @param std use only standard JSON syntax, i.e. convert tuples and variants into standard JSON (if applicable), refuse to print NaN and infinities, @@ -20,6 +23,7 @@ val to_string : val to_channel : ?buf:Buffer.t -> ?len:int -> + ?suf:string -> ?std:bool -> out_channel -> t -> unit (** Write a compact JSON value to a channel. @@ -30,6 +34,7 @@ val to_channel : val to_output : ?buf:Buffer.t -> ?len:int -> + ?suf:string -> ?std:bool -> < output : string -> int -> int -> int; .. > -> t -> unit (** Write a compact JSON value to an OO channel. @@ -39,14 +44,14 @@ val to_output : val to_file : ?len:int -> ?std:bool -> - ?newline:bool -> + ?suf:string -> string -> t -> unit (** Write a compact JSON value to a file. See [to_string] for the role of the optional arguments. - @param newline whether to end the content of the file with a new line. - Optional parameter with value [true] by default. *) + @param suf is the final character of the output. Newline by default. *) val to_buffer : + ?suf:string -> ?std:bool -> Buffer.t -> t -> unit (** Write a compact JSON value to an existing buffer. @@ -55,35 +60,43 @@ val to_buffer : val seq_to_string : ?buf:Buffer.t -> ?len:int -> + ?suf:string -> ?std:bool -> t Seq.t -> string - (** Write a newline-separated sequence of compact one-line JSON values to + (** Write a [suf]-separated sequence of 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. *) val seq_to_channel : ?buf:Buffer.t -> ?len:int -> + ?suf:string -> ?std:bool -> out_channel -> t Seq.t -> unit - (** Write a newline-separated sequence of compact one-line JSON values to + (** Write a [suf]-separated sequence of 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. *) val seq_to_file : ?len:int -> + ?suf:string -> ?std:bool -> string -> t Seq.t -> unit - (** Write a newline-separated sequence of compact one-line JSON values to + (** Write a [suf]-separated sequence of 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. *) val seq_to_buffer : + ?suf:string -> ?std:bool -> Buffer.t -> t Seq.t -> unit - (** Write a newline-separated sequence of compact one-line JSON values to + (** Write a [suf]-separated sequence of 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. *) val write_t : Buffer.t -> t -> unit