(* Toplevel printers for JMAP types Usage in toplevel: #require "jmap.top";; Printers are automatically installed when the library is loaded. *) (* JSON printers *) let json_printer ppf (json : Jsont.json) = match Jsont_bytesrw.encode_string Jsont.json json with | Ok s -> Format.pp_print_string ppf s | Error e -> Format.fprintf ppf "" e let jsont_error_printer ppf (e : Jsont.Error.t) = Format.pp_print_string ppf (Jsont.Error.to_string e) (* JSON encoding helpers *) let encode (type a) (codec : a Jsont.t) (value : a) : Jsont.json = match Jsont.Json.encode codec value with | Ok json -> json | Error e -> invalid_arg e let encode_string (type a) (codec : a Jsont.t) (value : a) : string = match Jsont_bytesrw.encode_string codec value with | Ok s -> s | Error e -> invalid_arg e let pp_as_json (type a) (codec : a Jsont.t) ppf (value : a) = json_printer ppf (encode codec value) (* Automatic printer installation *) let printers = [ "Jmap.Id.pp"; "Jmap.Keyword.pp"; "Jmap.Role.pp"; "Jmap.Capability.pp"; "Jmap.Error.pp"; "Jmap_top.json_printer"; "Jmap_top.jsont_error_printer" ] (* Suppress stderr during printer installation to avoid noise in MDX tests *) let null_formatter = Format.make_formatter (fun _ _ _ -> ()) (fun () -> ()) let eval_string_quiet str = try let lexbuf = Lexing.from_string str in let phrase = !Toploop.parse_toplevel_phrase lexbuf in Toploop.execute_phrase false null_formatter phrase with _ -> false let rec do_install_printers = function | [] -> true | printer :: rest -> let cmd = Printf.sprintf "#install_printer %s;;" printer in eval_string_quiet cmd && do_install_printers rest let install () = (* Silently ignore failures - this handles non-toplevel contexts like MDX *) ignore (do_install_printers printers) (* Only auto-install when OCAML_TOPLEVEL_NAME is set, indicating a real toplevel *) let () = if Sys.getenv_opt "OCAML_TOPLEVEL_NAME" <> None then install ()