Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

remove dep on easy-format #90

Merged
merged 2 commits into from
Jul 10, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 30 additions & 36 deletions lib/pretty.ml
Original file line number Diff line number Diff line change
@@ -1,69 +1,63 @@
open Printf

let array = Easy_format.list
let record = Easy_format.list
let tuple = { Easy_format.list with
space_after_opening = false;
space_before_closing = false;
align_closing = false }
let variant = { Easy_format.list with
space_before_closing = false; }
let pp_list sep ppx out l =
let pp_sep out () = Format.fprintf out "%s@ " sep in
Format.pp_print_list ~pp_sep ppx out l

let rec format std (x : t) =
let rec format std (out:Format.formatter) (x : t) : unit =
match x with
`Null -> Easy_format.Atom ("null", Easy_format.atom)
| `Bool x -> Easy_format.Atom ((if x then "true" else "false"), Easy_format.atom)
| `Int x -> Easy_format.Atom (json_string_of_int x, Easy_format.atom)
| `Null -> Format.pp_print_string out "null"
| `Bool x -> Format.pp_print_bool out x
| `Int x -> Format.pp_print_string out (json_string_of_int x)
| `Float x ->
let s =
if std then std_json_string_of_float x
else json_string_of_float x
in
Easy_format.Atom (s, Easy_format.atom)
| `String s -> Easy_format.Atom (json_string_of_string s, Easy_format.atom)
Format.pp_print_string out s
| `String s -> Format.pp_print_string out (json_string_of_string s)
| `Intlit s
| `Floatlit s
| `Stringlit s -> Easy_format.Atom (s, Easy_format.atom)
| `List [] -> Easy_format.Atom ("[]", Easy_format.atom)
| `List l -> Easy_format.List (("[", ",", "]", array), List.map (format std) l)
| `Assoc [] -> Easy_format.Atom ("{}", Easy_format.atom)
| `Assoc l -> Easy_format.List (("{", ",", "}", record), List.map (format_field std) l)
| `Stringlit s -> Format.pp_print_string out s
| `List [] -> Format.pp_print_string out "[]"
| `List l -> Format.fprintf out "[@;<1 0>@[<hov>%a@]@;<1 -2>]" (pp_list "," (format std)) l
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am a bit confused why the indentation adds 0 in the beginning but removes 2 in the end?

On a "less of a question, more of a comment"-front, I would expect JSON to be formatted [1, 2, 3], that is, without the spaces, but I just checked the old implementation and it does the exact same thing ([ 1, 2, 3 ]) so it makes sense to match what it was doing.

| `Assoc [] -> Format.pp_print_string out "{}"
| `Assoc l ->
Format.fprintf out "{@;<1 0>%a@;<1 -2>}" (pp_list "," (format_field std)) l
| `Tuple l ->
if std then
format std (`List l)
format std out (`List l)
else
if l = [] then
Easy_format.Atom ("()", Easy_format.atom)
Format.pp_print_string out "()"
else
Easy_format.List (("(", ",", ")", tuple), List.map (format std) l)
Format.fprintf out "(@,%a@;<0 -2>)" (pp_list "," (format std)) l
Copy link
Member

@Leonidas-from-XIV Leonidas-from-XIV Jul 10, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am wondering whether there should be a break-hint after the first (? Or is @, equivalent to @;<0 0>?

Got the question answered on IRC: Yes it is exactly the same.


| `Variant (s, None) ->
if std then
format std (`String s)
format std out (`String s)
else
Easy_format.Atom ("<" ^ json_string_of_string s ^ ">", Easy_format.atom)
Format.fprintf out "<%s>" (json_string_of_string s)

| `Variant (s, Some x) ->
if std then
format std (`List [ `String s; x ])
format std out (`List [ `String s; x ])
else
let op = "<" ^ json_string_of_string s ^ ":" in
Easy_format.List ((op, "", ">", variant), [format std x])
let op = json_string_of_string s in
Format.fprintf out "<@[<hv2>%s: %a@]>" op (format std) x
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It took me a while to understand that <hv2> probably means <hv 2>, correct? Maybe adding the space would alleviate the confusion for future readers?


and format_field std (name, x) =
let s = sprintf "%s:" (json_string_of_string name) in
Easy_format.Label ((Easy_format.Atom (s, Easy_format.atom), Easy_format.label), format std x)
and format_field std out (name, x) =
Format.fprintf out "@[<hv2>%s: %a@]" (json_string_of_string name) (format std) x


let format ?(std = false) x =
let pp ?(std = false) out x =
if std && not (is_object_or_array x) then
json_error
"Root is not an object or array as requested by the JSON standard"
else
format std (x :> t)
Format.fprintf out "@[<hv2>%a@]" (format std) (x :> t)

let to_string ?std x =
Easy_format.Pretty.to_string (format ?std x)
Format.asprintf "%a" (pp ?std) x

let to_channel ?std oc x =
Easy_format.Pretty.to_channel oc (format ?std x)
let fmt = Format.formatter_of_out_channel oc in
Format.fprintf fmt "%a@?" (pp ?std) x
2 changes: 1 addition & 1 deletion lib/pretty.mli
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
val format : ?std:bool -> json -> Easy_format.t
val pp : ?std:bool -> Format.formatter -> json -> unit
val to_string : ?std:bool -> json -> string
val to_channel : ?std:bool -> out_channel -> json -> unit
4 changes: 1 addition & 3 deletions lib/write2.ml
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
let pretty_format ?std (x : t) =
Pretty.format ?std (x :> json_max)

let pretty_print ?std out (x : t) =
Easy_format.Pretty.to_formatter out (pretty_format ?std x)
Pretty.pp ?std out (x :> json_max)

let pretty_to_string ?std (x : t) =
Pretty.to_string ?std (x :> json_max)
Expand Down
7 changes: 0 additions & 7 deletions lib/write2.mli
Original file line number Diff line number Diff line change
@@ -1,12 +1,5 @@
(** {2 JSON pretty-printing} *)

val pretty_format : ?std:bool -> t -> Easy_format.t
(** Convert into a pretty-printable tree.
See [to_string] for the role of the optional [std] argument.

@see <http://martin.jambon.free.fr/easy-format.html> Easy-format
*)

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.
Expand Down
16 changes: 16 additions & 0 deletions test/pretty/dune
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
(executable
(name test)
(libraries yojson))

(rule
(targets test.output)
(deps ./sample.json ./test.exe)
(action
(with-stdout-to
%{targets}
(run ./test.exe))))

(alias
(name runtest)
(action
(diff test.expected test.output)))
18 changes: 18 additions & 0 deletions test/pretty/sample.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"abc": [ 1, 2, -3 ],
cd: (1.2, "zz"),
ef : [ <Int:123>, <Null>, <Test:"abcdefghijklmnopqrstuvwxyz"> ],
aaaaoooaoaooooooooaoaoaoooaoa: {
"big int": 123456789012345678901837292020484756564574
},
"array": [
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0
],
"'NULL' U+0000": "\u0000",
"'VULGAR FRACTION ONE HALF' U+00BD": "\u00BD",
"'PILE OF POO' U+1F4A9": "\uD83D\uDCA9",
"min_int": "-4611686018427387904"
}
18 changes: 18 additions & 0 deletions test/pretty/test.expected
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"abc": [ 1, 2, -3 ],
"cd": (1.2, "zz"),
"ef": [ <"Int": 123>, <"Null">, <"Test": "abcdefghijklmnopqrstuvwxyz"> ],
"aaaaoooaoaooooooooaoaoaoooaoa": {
"big int": 123456789012345678901837292020484756564574
},
"array": [
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0
],
"'NULL' U+0000": "\u0000",
"'VULGAR FRACTION ONE HALF' U+00BD": "½",
"'PILE OF POO' U+1F4A9": "💩",
"min_int": "-4611686018427387904"
}
7 changes: 7 additions & 0 deletions test/pretty/test.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module J = Yojson.Safe

let () =
let j = J.from_file "sample.json" in
Format.printf "%a@." (J.pretty_print ?std:None) j;
()

1 change: 0 additions & 1 deletion yojson.opam
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ depends: [
"ocaml" {>= "4.02.3"}
"dune"
"cppo" {build}
"easy-format"
"biniou" {>= "1.2.0"}
"alcotest" {with-test & >= "0.8.5"}
]
Expand Down