RFC6901 JSON Pointer implementation in OCaml using jsont

rename to json-pointer

+2 -2
bin/dune
··· 1 (executable 2 (name jsonpp) 3 (public_name jsonpp) 4 - (package jsont-pointer) 5 - (libraries jsont jsont.bytesrw jsont_pointer))
··· 1 (executable 2 (name jsonpp) 3 (public_name jsonpp) 4 + (package json-pointer) 5 + (libraries jsont jsont.bytesrw json_pointer))
+31 -31
bin/jsonpp.ml
··· 1 - (* Test runner for jsont_pointer *) 2 3 let read_file path = 4 let ic = open_in path in ··· 18 | Error e -> failwith e 19 20 (* Helper to get indices from any pointer *) 21 - let indices_of_any (Jsont_pointer.Any p) = Jsont_pointer.indices p 22 23 (* Helper to convert to string from any pointer *) 24 - let to_string_of_any (Jsont_pointer.Any p) = Jsont_pointer.to_string p 25 26 (* Helper to check if pointer is append *) 27 - let is_append_any (Jsont_pointer.Any p : Jsont_pointer.any) = 28 - not (Jsont_pointer.is_nav (Jsont_pointer.Any p)) 29 30 (* Test: parse pointer and print indices *) 31 let test_parse pointer_str = 32 try 33 - let result = Jsont_pointer.of_string pointer_str in 34 let indices = indices_of_any result in 35 let index_strs = List.map (fun idx -> 36 match idx with ··· 45 (* Test: roundtrip pointer string *) 46 let test_roundtrip pointer_str = 47 try 48 - let result = Jsont_pointer.of_string pointer_str in 49 let s = to_string_of_any result in 50 if s = pointer_str then 51 Printf.printf "OK: %s\n" s ··· 58 let test_eval json_path pointer_str = 59 try 60 let json = parse_json (read_file json_path) in 61 - let p = Jsont_pointer.of_string_nav pointer_str in 62 - let result = Jsont_pointer.get p json in 63 Printf.printf "OK: %s\n" (json_to_string result) 64 with 65 | Jsont.Error e -> ··· 69 70 (* Test: escape token *) 71 let test_escape token = 72 - let escaped = Jsont_pointer.Token.escape token in 73 Printf.printf "%s\n" escaped 74 75 (* Test: unescape token *) 76 let test_unescape token = 77 try 78 - let unescaped = Jsont_pointer.Token.unescape token in 79 Printf.printf "OK: %s\n" unescaped 80 with Jsont.Error e -> 81 Printf.printf "ERROR: %s\n" (Jsont.Error.to_string e) ··· 83 (* Test: URI fragment roundtrip *) 84 let test_uri_fragment pointer_str = 85 try 86 - let result = Jsont_pointer.of_string pointer_str in 87 - let (Jsont_pointer.Any p) = result in 88 - let frag = Jsont_pointer.to_uri_fragment p in 89 - let result2 = Jsont_pointer.of_uri_fragment frag in 90 let s2 = to_string_of_any result2 in 91 if s2 = pointer_str then 92 Printf.printf "OK: %s -> %s\n" pointer_str frag ··· 100 try 101 let json = parse_json json_str in 102 let value = parse_json value_str in 103 - let p = Jsont_pointer.of_string pointer_str in 104 - let result = Jsont_pointer.add p json ~value in 105 Printf.printf "%s\n" (json_to_string result) 106 with Jsont.Error e -> 107 Printf.printf "ERROR: %s\n" (Jsont.Error.to_string e) ··· 110 let test_remove json_str pointer_str = 111 try 112 let json = parse_json json_str in 113 - let p = Jsont_pointer.of_string_nav pointer_str in 114 - let result = Jsont_pointer.remove p json in 115 Printf.printf "%s\n" (json_to_string result) 116 with Jsont.Error e -> 117 Printf.printf "ERROR: %s\n" (Jsont.Error.to_string e) ··· 120 let test_replace json_str pointer_str value_str = 121 try 122 let json = parse_json json_str in 123 - let p = Jsont_pointer.of_string_nav pointer_str in 124 let value = parse_json value_str in 125 - let result = Jsont_pointer.replace p json ~value in 126 Printf.printf "%s\n" (json_to_string result) 127 with Jsont.Error e -> 128 Printf.printf "ERROR: %s\n" (Jsont.Error.to_string e) ··· 131 let test_move json_str from_str path_str = 132 try 133 let json = parse_json json_str in 134 - let from = Jsont_pointer.of_string_nav from_str in 135 - let path = Jsont_pointer.of_string path_str in 136 - let result = Jsont_pointer.move ~from ~path json in 137 Printf.printf "%s\n" (json_to_string result) 138 with Jsont.Error e -> 139 Printf.printf "ERROR: %s\n" (Jsont.Error.to_string e) ··· 142 let test_copy json_str from_str path_str = 143 try 144 let json = parse_json json_str in 145 - let from = Jsont_pointer.of_string_nav from_str in 146 - let path = Jsont_pointer.of_string path_str in 147 - let result = Jsont_pointer.copy ~from ~path json in 148 Printf.printf "%s\n" (json_to_string result) 149 with Jsont.Error e -> 150 Printf.printf "ERROR: %s\n" (Jsont.Error.to_string e) ··· 153 let test_test json_str pointer_str expected_str = 154 try 155 let json = parse_json json_str in 156 - let p = Jsont_pointer.of_string_nav pointer_str in 157 let expected = parse_json expected_str in 158 - let result = Jsont_pointer.test p json ~expected in 159 Printf.printf "%b\n" result 160 with Jsont.Error e -> 161 Printf.printf "ERROR: %s\n" (Jsont.Error.to_string e) ··· 164 let test_has json_str pointer_str = 165 try 166 let json = parse_json json_str in 167 - let p = Jsont_pointer.of_string_nav pointer_str in 168 - let result = Jsont_pointer.find p json in 169 Printf.printf "%b\n" (Option.is_some result) 170 with Jsont.Error e -> 171 Printf.printf "ERROR: %s\n" (Jsont.Error.to_string e)
··· 1 + (* Test runner for json_pointer *) 2 3 let read_file path = 4 let ic = open_in path in ··· 18 | Error e -> failwith e 19 20 (* Helper to get indices from any pointer *) 21 + let indices_of_any (Json_pointer.Any p) = Json_pointer.indices p 22 23 (* Helper to convert to string from any pointer *) 24 + let to_string_of_any (Json_pointer.Any p) = Json_pointer.to_string p 25 26 (* Helper to check if pointer is append *) 27 + let is_append_any (Json_pointer.Any p : Json_pointer.any) = 28 + not (Json_pointer.is_nav (Json_pointer.Any p)) 29 30 (* Test: parse pointer and print indices *) 31 let test_parse pointer_str = 32 try 33 + let result = Json_pointer.of_string pointer_str in 34 let indices = indices_of_any result in 35 let index_strs = List.map (fun idx -> 36 match idx with ··· 45 (* Test: roundtrip pointer string *) 46 let test_roundtrip pointer_str = 47 try 48 + let result = Json_pointer.of_string pointer_str in 49 let s = to_string_of_any result in 50 if s = pointer_str then 51 Printf.printf "OK: %s\n" s ··· 58 let test_eval json_path pointer_str = 59 try 60 let json = parse_json (read_file json_path) in 61 + let p = Json_pointer.of_string_nav pointer_str in 62 + let result = Json_pointer.get p json in 63 Printf.printf "OK: %s\n" (json_to_string result) 64 with 65 | Jsont.Error e -> ··· 69 70 (* Test: escape token *) 71 let test_escape token = 72 + let escaped = Json_pointer.Token.escape token in 73 Printf.printf "%s\n" escaped 74 75 (* Test: unescape token *) 76 let test_unescape token = 77 try 78 + let unescaped = Json_pointer.Token.unescape token in 79 Printf.printf "OK: %s\n" unescaped 80 with Jsont.Error e -> 81 Printf.printf "ERROR: %s\n" (Jsont.Error.to_string e) ··· 83 (* Test: URI fragment roundtrip *) 84 let test_uri_fragment pointer_str = 85 try 86 + let result = Json_pointer.of_string pointer_str in 87 + let (Json_pointer.Any p) = result in 88 + let frag = Json_pointer.to_uri_fragment p in 89 + let result2 = Json_pointer.of_uri_fragment frag in 90 let s2 = to_string_of_any result2 in 91 if s2 = pointer_str then 92 Printf.printf "OK: %s -> %s\n" pointer_str frag ··· 100 try 101 let json = parse_json json_str in 102 let value = parse_json value_str in 103 + let p = Json_pointer.of_string pointer_str in 104 + let result = Json_pointer.add p json ~value in 105 Printf.printf "%s\n" (json_to_string result) 106 with Jsont.Error e -> 107 Printf.printf "ERROR: %s\n" (Jsont.Error.to_string e) ··· 110 let test_remove json_str pointer_str = 111 try 112 let json = parse_json json_str in 113 + let p = Json_pointer.of_string_nav pointer_str in 114 + let result = Json_pointer.remove p json in 115 Printf.printf "%s\n" (json_to_string result) 116 with Jsont.Error e -> 117 Printf.printf "ERROR: %s\n" (Jsont.Error.to_string e) ··· 120 let test_replace json_str pointer_str value_str = 121 try 122 let json = parse_json json_str in 123 + let p = Json_pointer.of_string_nav pointer_str in 124 let value = parse_json value_str in 125 + let result = Json_pointer.replace p json ~value in 126 Printf.printf "%s\n" (json_to_string result) 127 with Jsont.Error e -> 128 Printf.printf "ERROR: %s\n" (Jsont.Error.to_string e) ··· 131 let test_move json_str from_str path_str = 132 try 133 let json = parse_json json_str in 134 + let from = Json_pointer.of_string_nav from_str in 135 + let path = Json_pointer.of_string path_str in 136 + let result = Json_pointer.move ~from ~path json in 137 Printf.printf "%s\n" (json_to_string result) 138 with Jsont.Error e -> 139 Printf.printf "ERROR: %s\n" (Jsont.Error.to_string e) ··· 142 let test_copy json_str from_str path_str = 143 try 144 let json = parse_json json_str in 145 + let from = Json_pointer.of_string_nav from_str in 146 + let path = Json_pointer.of_string path_str in 147 + let result = Json_pointer.copy ~from ~path json in 148 Printf.printf "%s\n" (json_to_string result) 149 with Jsont.Error e -> 150 Printf.printf "ERROR: %s\n" (Jsont.Error.to_string e) ··· 153 let test_test json_str pointer_str expected_str = 154 try 155 let json = parse_json json_str in 156 + let p = Json_pointer.of_string_nav pointer_str in 157 let expected = parse_json expected_str in 158 + let result = Json_pointer.test p json ~expected in 159 Printf.printf "%b\n" result 160 with Jsont.Error e -> 161 Printf.printf "ERROR: %s\n" (Jsont.Error.to_string e) ··· 164 let test_has json_str pointer_str = 165 try 166 let json = parse_json json_str in 167 + let p = Json_pointer.of_string_nav pointer_str in 168 + let result = Json_pointer.find p json in 169 Printf.printf "%b\n" (Option.is_some result) 170 with Jsont.Error e -> 171 Printf.printf "ERROR: %s\n" (Jsont.Error.to_string e)
+2 -2
doc/dune
··· 1 (mdx 2 (files tutorial.mld) 3 - (libraries jsont jsont.bytesrw jsont_pointer jsont_pointer_top)) 4 5 (documentation 6 - (package jsont-pointer) 7 (mld_files index tutorial))
··· 1 (mdx 2 (files tutorial.mld) 3 + (libraries jsont jsont.bytesrw json_pointer json_pointer_top)) 4 5 (documentation 6 + (package json-pointer) 7 (mld_files index tutorial))
+2 -2
doc/index.mld
··· 1 - {0 jsont-pointer} 2 3 - {!modules: Jsont_pointer Jsont_pointer_top} 4 5 {1 Tutorial} 6
··· 1 + {0 json-pointer} 2 3 + {!modules: Json_pointer Json_pointer_top} 4 5 {1 Tutorial} 6
+10 -10
doc/tutorial.mld
··· 2 3 This tutorial introduces JSON Pointer as defined in 4 {{:https://www.rfc-editor.org/rfc/rfc6901} RFC 6901}, and demonstrates 5 - the [jsont-pointer] OCaml library through interactive examples. 6 7 {1 JSON Pointer vs JSON Path} 8 ··· 20 (like JSON Schema's [$ref]). Use JSON Path when you might need multiple 21 results (like Kubernetes queries). 22 23 - The [jsont-pointer] library implements JSON Pointer and integrates with 24 the {!Jsont.Path} type for representing navigation indices. 25 26 {1 Setup} 27 28 First, let's set up our environment. In the toplevel, you can load the 29 - library with [#require "jsont-pointer.top";;] which will automatically 30 install pretty printers. 31 32 {@ocaml[ 33 - # Jsont_pointer_top.install ();; 34 - : unit = () 35 - # open Jsont_pointer;; 36 # let parse_json s = 37 match Jsont_bytesrw.decode_string Jsont.json s with 38 | Ok json -> json ··· 73 - : Jsont.json = "Alice" 74 ]} 75 76 - In OCaml, this is represented by the ['a Jsont_pointer.t] type - a sequence 77 of navigation steps from the document root to a target value. The phantom 78 type parameter ['a] encodes whether this is a navigation pointer or an 79 append pointer (more on this later). ··· 365 366 {2 Navigation vs Append Pointers} 367 368 - The [jsont-pointer] library uses {b phantom types} to encode the difference 369 between pointers that can be used for navigation and pointers that target 370 the "append position": 371 ··· 439 {1 Mutation Operations} 440 441 While RFC 6901 defines JSON Pointer for read-only access, RFC 6902 442 - (JSON Patch) uses JSON Pointer for modifications. The [jsont-pointer] 443 library provides these operations. 444 445 {2 Add} ··· 582 583 {2 The Library Handles Escaping Automatically} 584 585 - {b Important}: When using [jsont-pointer] programmatically, you rarely need 586 to think about escaping. The [Mem] variant stores unescaped strings, 587 and escaping happens automatically during serialization: 588 ··· 882 {- {b Type Safety}: Phantom types ([nav t] vs [append t]) prevent misuse of append pointers with retrieval operations, while the [any] existential type allows ergonomic use with mutation operations} 883 } 884 885 - The [jsont-pointer] library implements all of this with type-safe OCaml 886 interfaces, integration with the [jsont] codec system, and proper error 887 handling for malformed pointers and missing values. 888
··· 2 3 This tutorial introduces JSON Pointer as defined in 4 {{:https://www.rfc-editor.org/rfc/rfc6901} RFC 6901}, and demonstrates 5 + the [json-pointer] OCaml library through interactive examples. 6 7 {1 JSON Pointer vs JSON Path} 8 ··· 20 (like JSON Schema's [$ref]). Use JSON Path when you might need multiple 21 results (like Kubernetes queries). 22 23 + The [json-pointer] library implements JSON Pointer and integrates with 24 the {!Jsont.Path} type for representing navigation indices. 25 26 {1 Setup} 27 28 First, let's set up our environment. In the toplevel, you can load the 29 + library with [#require "json-pointer.top";;] which will automatically 30 install pretty printers. 31 32 {@ocaml[ 33 + # Json_pointer_top.install ();; 34 - : unit = () 35 + # open Json_pointer;; 36 # let parse_json s = 37 match Jsont_bytesrw.decode_string Jsont.json s with 38 | Ok json -> json ··· 73 - : Jsont.json = "Alice" 74 ]} 75 76 + In OCaml, this is represented by the ['a Json_pointer.t] type - a sequence 77 of navigation steps from the document root to a target value. The phantom 78 type parameter ['a] encodes whether this is a navigation pointer or an 79 append pointer (more on this later). ··· 365 366 {2 Navigation vs Append Pointers} 367 368 + The [json-pointer] library uses {b phantom types} to encode the difference 369 between pointers that can be used for navigation and pointers that target 370 the "append position": 371 ··· 439 {1 Mutation Operations} 440 441 While RFC 6901 defines JSON Pointer for read-only access, RFC 6902 442 + (JSON Patch) uses JSON Pointer for modifications. The [json-pointer] 443 library provides these operations. 444 445 {2 Add} ··· 582 583 {2 The Library Handles Escaping Automatically} 584 585 + {b Important}: When using [json-pointer] programmatically, you rarely need 586 to think about escaping. The [Mem] variant stores unescaped strings, 587 and escaping happens automatically during serialization: 588 ··· 882 {- {b Type Safety}: Phantom types ([nav t] vs [append t]) prevent misuse of append pointers with retrieval operations, while the [any] existential type allows ergonomic use with mutation operations} 883 } 884 885 + The [json-pointer] library implements all of this with type-safe OCaml 886 interfaces, integration with the [jsont] codec system, and proper error 887 handling for malformed pointers and missing values. 888
+2 -2
dune-project
··· 1 (lang dune 3.20) 2 (using mdx 0.4) 3 4 - (name jsont-pointer) 5 6 (generate_opam_files true) 7 ··· 13 (maintenance_intent "(latest)") 14 15 (package 16 - (name jsont-pointer) 17 (synopsis "RFC 6901 JSON Pointer implementation for jsont") 18 (description 19 "This library provides RFC 6901 JSON Pointer parsing, serialization, \
··· 1 (lang dune 3.20) 2 (using mdx 0.4) 3 4 + (name json-pointer) 5 6 (generate_opam_files true) 7 ··· 13 (maintenance_intent "(latest)") 14 15 (package 16 + (name json-pointer) 17 (synopsis "RFC 6901 JSON Pointer implementation for jsont") 18 (description 19 "This library provides RFC 6901 JSON Pointer parsing, serialization, \
jsont-pointer.opam json-pointer.opam
+2 -2
src/dune
··· 1 (library 2 - (name jsont_pointer) 3 - (public_name jsont-pointer) 4 (libraries jsont))
··· 1 (library 2 + (name json_pointer) 3 + (public_name json-pointer) 4 (libraries jsont))
src/jsont_pointer.ml src/json_pointer.ml
src/jsont_pointer.mli src/json_pointer.mli
+3 -3
src/top/dune
··· 1 (library 2 - (name jsont_pointer_top) 3 - (public_name jsont-pointer.top) 4 - (libraries jsont-pointer jsont.bytesrw compiler-libs))
··· 1 (library 2 + (name json_pointer_top) 3 + (public_name json-pointer.top) 4 + (libraries json-pointer jsont.bytesrw compiler-libs))
+10 -10
src/top/jsont_pointer_top.ml src/top/json_pointer_top.ml
··· 1 - (* Toplevel printers for Jsont_pointer.t, Jsont.json, and Jsont.Error.t 2 3 Usage in toplevel: 4 - #require "jsont-pointer.top";; 5 6 Printers are automatically installed when the library is loaded. 7 *) 8 9 - let nav_printer ppf (p : Jsont_pointer.nav Jsont_pointer.t) = 10 - Jsont_pointer.pp_verbose ppf p 11 12 - let append_printer ppf (p : Jsont_pointer.append Jsont_pointer.t) = 13 - Jsont_pointer.pp_verbose ppf p 14 15 let json_printer ppf (json : Jsont.json) = 16 match Jsont_bytesrw.encode_string Jsont.json json with ··· 23 (* Automatic printer installation *) 24 25 let printers = 26 - [ "Jsont_pointer_top.nav_printer"; 27 - "Jsont_pointer_top.append_printer"; 28 - "Jsont_pointer_top.json_printer"; 29 - "Jsont_pointer_top.error_printer" ] 30 31 (* Suppress stderr during printer installation to avoid noise in MDX tests *) 32 let null_formatter = Format.make_formatter (fun _ _ _ -> ()) (fun () -> ())
··· 1 + (* Toplevel printers for Json_pointer.t, Jsont.json, and Jsont.Error.t 2 3 Usage in toplevel: 4 + #require "json-pointer.top";; 5 6 Printers are automatically installed when the library is loaded. 7 *) 8 9 + let nav_printer ppf (p : Json_pointer.nav Json_pointer.t) = 10 + Json_pointer.pp_verbose ppf p 11 12 + let append_printer ppf (p : Json_pointer.append Json_pointer.t) = 13 + Json_pointer.pp_verbose ppf p 14 15 let json_printer ppf (json : Jsont.json) = 16 match Jsont_bytesrw.encode_string Jsont.json json with ··· 23 (* Automatic printer installation *) 24 25 let printers = 26 + [ "Json_pointer_top.nav_printer"; 27 + "Json_pointer_top.append_printer"; 28 + "Json_pointer_top.json_printer"; 29 + "Json_pointer_top.error_printer" ] 30 31 (* Suppress stderr during printer installation to avoid noise in MDX tests *) 32 let null_formatter = Format.make_formatter (fun _ _ _ -> ()) (fun () -> ())
+7 -7
src/top/jsont_pointer_top.mli src/top/json_pointer_top.mli
··· 1 - (** Toplevel printers for {!Jsont_pointer}, {!Jsont.json}, and {!Jsont.Error.t}. 2 3 Printers are automatically installed when the library is loaded: 4 {[ 5 - #require "jsont-pointer.top";; 6 ]} 7 8 After loading, JSON Pointers will display their structure: 9 {[ 10 - # Jsont_pointer.of_string_nav "/foo/0";; 11 - - : Jsont_pointer.nav Jsont_pointer.t = [Mem "foo"; Nth 0] 12 ]} 13 14 JSON values will display as formatted JSON strings: ··· 19 20 And errors will display as readable messages: 21 {[ 22 - # Jsont_pointer.of_string "invalid";; 23 Exception: Jsont.Error: Invalid JSON Pointer: must be empty or start with '/' 24 ]} *) 25 26 - val nav_printer : Format.formatter -> Jsont_pointer.nav Jsont_pointer.t -> unit 27 (** [nav_printer] formats a navigation JSON Pointer showing its index structure. 28 Suitable for use with [#install_printer]. *) 29 30 - val append_printer : Format.formatter -> Jsont_pointer.append Jsont_pointer.t -> unit 31 (** [append_printer] formats an append JSON Pointer showing its index structure. 32 Suitable for use with [#install_printer]. *) 33
··· 1 + (** Toplevel printers for {!Json_pointer}, {!Jsont.json}, and {!Jsont.Error.t}. 2 3 Printers are automatically installed when the library is loaded: 4 {[ 5 + #require "json-pointer.top";; 6 ]} 7 8 After loading, JSON Pointers will display their structure: 9 {[ 10 + # Json_pointer.of_string_nav "/foo/0";; 11 + - : Json_pointer.nav Json_pointer.t = [Mem "foo"; Nth 0] 12 ]} 13 14 JSON values will display as formatted JSON strings: ··· 19 20 And errors will display as readable messages: 21 {[ 22 + # Json_pointer.of_string "invalid";; 23 Exception: Jsont.Error: Invalid JSON Pointer: must be empty or start with '/' 24 ]} *) 25 26 + val nav_printer : Format.formatter -> Json_pointer.nav Json_pointer.t -> unit 27 (** [nav_printer] formats a navigation JSON Pointer showing its index structure. 28 Suitable for use with [#install_printer]. *) 29 30 + val append_printer : Format.formatter -> Json_pointer.append Json_pointer.t -> unit 31 (** [append_printer] formats an append JSON Pointer showing its index structure. 32 Suitable for use with [#install_printer]. *) 33
+1 -1
test/api.t
··· 1 JSON Pointer API Test Suite 2 3 - This tests all functions exposed in jsont_pointer.mli. 4 5 ================================================================================ 6 Index Functions (mem, nth, pp_index, equal_index, compare_index)
··· 1 JSON Pointer API Test Suite 2 3 + This tests all functions exposed in json_pointer.mli. 4 5 ================================================================================ 6 Index Functions (mem, nth, pp_index, equal_index, compare_index)
+1 -1
test/dune
··· 1 (executable 2 (name test_pointer) 3 - (libraries jsont jsont.bytesrw jsont_pointer)) 4 5 (cram 6 (deps test_pointer.exe
··· 1 (executable 2 (name test_pointer) 3 + (libraries jsont jsont.bytesrw json_pointer)) 4 5 (cram 6 (deps test_pointer.exe
+152 -152
test/test_pointer.ml
··· 1 - (* Test runner for jsont_pointer *) 2 3 let read_file path = 4 let ic = open_in path in ··· 18 | Error e -> failwith e 19 20 (* Helper to get indices from any pointer *) 21 - let indices_of_any (Jsont_pointer.Any p) = Jsont_pointer.indices p 22 23 (* Helper to convert to string from any pointer *) 24 - let to_string_of_any (Jsont_pointer.Any p) = Jsont_pointer.to_string p 25 26 (* Helper to check if pointer is append *) 27 - let is_append_any p = not (Jsont_pointer.is_nav p) 28 29 (* Test: parse pointer and print indices *) 30 let test_parse pointer_str = 31 try 32 - let result = Jsont_pointer.of_string pointer_str in 33 let indices = indices_of_any result in 34 let index_strs = List.map (fun idx -> 35 match idx with ··· 44 (* Test: roundtrip pointer string *) 45 let test_roundtrip pointer_str = 46 try 47 - let result = Jsont_pointer.of_string pointer_str in 48 let s = to_string_of_any result in 49 if s = pointer_str then 50 Printf.printf "OK: %s\n" s ··· 57 let test_eval json_path pointer_str = 58 try 59 let json = parse_json (read_file json_path) in 60 - let p = Jsont_pointer.of_string_nav pointer_str in 61 - let result = Jsont_pointer.get p json in 62 Printf.printf "OK: %s\n" (json_to_string result) 63 with 64 | Jsont.Error e -> ··· 68 69 (* Test: escape token *) 70 let test_escape token = 71 - let escaped = Jsont_pointer.Token.escape token in 72 Printf.printf "%s\n" escaped 73 74 (* Test: unescape token *) 75 let test_unescape token = 76 try 77 - let unescaped = Jsont_pointer.Token.unescape token in 78 Printf.printf "OK: %s\n" unescaped 79 with Jsont.Error e -> 80 Printf.printf "ERROR: %s\n" (Jsont.Error.to_string e) ··· 82 (* Test: URI fragment roundtrip *) 83 let test_uri_fragment pointer_str = 84 try 85 - let result = Jsont_pointer.of_string pointer_str in 86 - let (Jsont_pointer.Any p) = result in 87 - let frag = Jsont_pointer.to_uri_fragment p in 88 - let result2 = Jsont_pointer.of_uri_fragment frag in 89 let s2 = to_string_of_any result2 in 90 if s2 = pointer_str then 91 Printf.printf "OK: %s -> %s\n" pointer_str frag ··· 99 try 100 let json = parse_json json_str in 101 let value = parse_json value_str in 102 - let p = Jsont_pointer.of_string pointer_str in 103 - let result = Jsont_pointer.add p json ~value in 104 Printf.printf "%s\n" (json_to_string result) 105 with Jsont.Error e -> 106 Printf.printf "ERROR: %s\n" (Jsont.Error.to_string e) ··· 109 let test_remove json_str pointer_str = 110 try 111 let json = parse_json json_str in 112 - let p = Jsont_pointer.of_string_nav pointer_str in 113 - let result = Jsont_pointer.remove p json in 114 Printf.printf "%s\n" (json_to_string result) 115 with Jsont.Error e -> 116 Printf.printf "ERROR: %s\n" (Jsont.Error.to_string e) ··· 119 let test_replace json_str pointer_str value_str = 120 try 121 let json = parse_json json_str in 122 - let p = Jsont_pointer.of_string_nav pointer_str in 123 let value = parse_json value_str in 124 - let result = Jsont_pointer.replace p json ~value in 125 Printf.printf "%s\n" (json_to_string result) 126 with Jsont.Error e -> 127 Printf.printf "ERROR: %s\n" (Jsont.Error.to_string e) ··· 130 let test_move json_str from_str path_str = 131 try 132 let json = parse_json json_str in 133 - let from = Jsont_pointer.of_string_nav from_str in 134 - let path = Jsont_pointer.of_string path_str in 135 - let result = Jsont_pointer.move ~from ~path json in 136 Printf.printf "%s\n" (json_to_string result) 137 with Jsont.Error e -> 138 Printf.printf "ERROR: %s\n" (Jsont.Error.to_string e) ··· 141 let test_copy json_str from_str path_str = 142 try 143 let json = parse_json json_str in 144 - let from = Jsont_pointer.of_string_nav from_str in 145 - let path = Jsont_pointer.of_string path_str in 146 - let result = Jsont_pointer.copy ~from ~path json in 147 Printf.printf "%s\n" (json_to_string result) 148 with Jsont.Error e -> 149 Printf.printf "ERROR: %s\n" (Jsont.Error.to_string e) ··· 152 let test_test json_str pointer_str expected_str = 153 try 154 let json = parse_json json_str in 155 - let p = Jsont_pointer.of_string_nav pointer_str in 156 let expected = parse_json expected_str in 157 - let result = Jsont_pointer.test p json ~expected in 158 Printf.printf "%b\n" result 159 with Jsont.Error e -> 160 Printf.printf "ERROR: %s\n" (Jsont.Error.to_string e) ··· 163 let test_has json_str pointer_str = 164 try 165 let json = parse_json json_str in 166 - let p = Jsont_pointer.of_string_nav pointer_str in 167 - let result = Jsont_pointer.find p json in 168 Printf.printf "%b\n" (Option.is_some result) 169 with Jsont.Error e -> 170 Printf.printf "ERROR: %s\n" (Jsont.Error.to_string e) ··· 172 (* Test: JMAP extended pointer parse *) 173 let test_jmap_parse pointer_str = 174 try 175 - let p = Jsont_pointer.Jmap.of_string pointer_str in 176 - let s = Jsont_pointer.Jmap.to_string p in 177 if s = "" then Printf.printf "OK: (root)\n" 178 else Printf.printf "OK: %s\n" s 179 with Jsont.Error e -> ··· 183 let test_jmap_eval json_str pointer_str = 184 try 185 let json = parse_json json_str in 186 - let p = Jsont_pointer.Jmap.of_string pointer_str in 187 - let result = Jsont_pointer.Jmap.eval p json in 188 Printf.printf "OK: %s\n" (json_to_string result) 189 with 190 | Jsont.Error e -> ··· 196 let test_jmap_eval_file json_path pointer_str = 197 try 198 let json = parse_json (read_file json_path) in 199 - let p = Jsont_pointer.Jmap.of_string pointer_str in 200 - let result = Jsont_pointer.Jmap.eval p json in 201 Printf.printf "OK: %s\n" (json_to_string result) 202 with 203 | Jsont.Error e -> ··· 209 let test_jmap_path_strings json_str pointer_str = 210 try 211 let json = parse_json json_str in 212 - let p = Jsont_pointer.Jmap.of_string pointer_str in 213 - let codec = Jsont_pointer.Jmap.path_list p Jsont.string in 214 let result = match Jsont.Json.decode' codec json with 215 | Ok v -> v 216 | Error e -> raise (Jsont.Error e) ··· 226 let test_jmap_path_ints json_str pointer_str = 227 try 228 let json = parse_json json_str in 229 - let p = Jsont_pointer.Jmap.of_string pointer_str in 230 - let codec = Jsont_pointer.Jmap.path_list p Jsont.int in 231 let result = match Jsont.Json.decode' codec json with 232 | Ok v -> v 233 | Error e -> raise (Jsont.Error e) ··· 243 let test_jmap_path_single json_str pointer_str = 244 try 245 let json = parse_json json_str in 246 - let p = Jsont_pointer.Jmap.of_string pointer_str in 247 - let codec = Jsont_pointer.Jmap.path p Jsont.string in 248 let result = match Jsont.Json.decode' codec json with 249 | Ok v -> v 250 | Error e -> raise (Jsont.Error e) ··· 260 let test_jmap_path_absent json_str pointer_str default = 261 try 262 let json = parse_json json_str in 263 - let p = Jsont_pointer.Jmap.of_string pointer_str in 264 - let codec = Jsont_pointer.Jmap.path ~absent:default p Jsont.string in 265 let result = match Jsont.Json.decode' codec json with 266 | Ok v -> v 267 | Error e -> raise (Jsont.Error e) ··· 275 276 (* Test: index functions - mem, nth, pp_index, equal_index, compare_index *) 277 let test_mem name = 278 - let idx = Jsont_pointer.mem name in 279 - Format.printf "mem(%s) = %a\n" name Jsont_pointer.pp_index idx 280 281 let test_nth n = 282 - let idx = Jsont_pointer.nth n in 283 - Format.printf "nth(%d) = %a\n" n Jsont_pointer.pp_index idx 284 285 let test_equal_index idx1_str idx2_str = 286 let parse_idx s = 287 if String.length s > 0 && s.[0] >= '0' && s.[0] <= '9' then 288 - Jsont_pointer.nth (int_of_string s) 289 else 290 - Jsont_pointer.mem s 291 in 292 let idx1 = parse_idx idx1_str in 293 let idx2 = parse_idx idx2_str in 294 - Printf.printf "%b\n" (Jsont_pointer.equal_index idx1 idx2) 295 296 let test_compare_index idx1_str idx2_str = 297 let parse_idx s = 298 if String.length s > 0 && s.[0] >= '0' && s.[0] <= '9' then 299 - Jsont_pointer.nth (int_of_string s) 300 else 301 - Jsont_pointer.mem s 302 in 303 let idx1 = parse_idx idx1_str in 304 let idx2 = parse_idx idx2_str in 305 - let cmp = Jsont_pointer.compare_index idx1 idx2 in 306 if cmp < 0 then Printf.printf "LT\n" 307 else if cmp > 0 then Printf.printf "GT\n" 308 else Printf.printf "EQ\n" 309 310 (* Test: pointer constructors - root, is_root, make *) 311 let test_root () = 312 - let r = Jsont_pointer.root in 313 - Printf.printf "root = %s\n" (Jsont_pointer.to_string r); 314 - Printf.printf "is_root(root) = %b\n" (Jsont_pointer.is_root r) 315 316 let test_is_root pointer_str = 317 try 318 - let p = Jsont_pointer.of_string pointer_str in 319 - let (Jsont_pointer.Any ptr) = p in 320 - Printf.printf "%b\n" (Jsont_pointer.is_root ptr) 321 with Jsont.Error e -> 322 Printf.printf "ERROR: %s\n" (Jsont.Error.to_string e) 323 ··· 326 let parts = String.split_on_char ',' indices_str in 327 let indices = List.map (fun s -> 328 let s = String.trim s in 329 - if s = "" then Jsont_pointer.mem "" 330 else if String.length s > 0 && s.[0] >= '0' && s.[0] <= '9' then 331 - Jsont_pointer.nth (int_of_string s) 332 else 333 - Jsont_pointer.mem s 334 ) parts in 335 - let p = Jsont_pointer.make indices in 336 - Printf.printf "%s\n" (Jsont_pointer.to_string p) 337 338 (* Test: append_index and / operator *) 339 let test_append_index base_str index_str = 340 try 341 - let base = Jsont_pointer.of_string_nav base_str in 342 let idx = 343 if String.length index_str > 0 && index_str.[0] >= '0' && index_str.[0] <= '9' then 344 - Jsont_pointer.nth (int_of_string index_str) 345 else 346 - Jsont_pointer.mem index_str 347 in 348 - let result = Jsont_pointer.(base / idx) in 349 - Printf.printf "%s\n" (Jsont_pointer.to_string result) 350 with Jsont.Error e -> 351 Printf.printf "ERROR: %s\n" (Jsont.Error.to_string e) 352 353 (* Test: at_end *) 354 let test_at_end pointer_str = 355 try 356 - let p = Jsont_pointer.of_string_nav pointer_str in 357 - let append_p = Jsont_pointer.at_end p in 358 - Printf.printf "%s\n" (Jsont_pointer.to_string append_p) 359 with Jsont.Error e -> 360 Printf.printf "ERROR: %s\n" (Jsont.Error.to_string e) 361 362 (* Test: concat *) 363 let test_concat p1_str p2_str = 364 try 365 - let p1 = Jsont_pointer.of_string_nav p1_str in 366 - let p2 = Jsont_pointer.of_string_nav p2_str in 367 - let result = Jsont_pointer.concat p1 p2 in 368 - Printf.printf "%s\n" (Jsont_pointer.to_string result) 369 with Jsont.Error e -> 370 Printf.printf "ERROR: %s\n" (Jsont.Error.to_string e) 371 372 (* Test: parent *) 373 let test_parent pointer_str = 374 try 375 - let p = Jsont_pointer.of_string_nav pointer_str in 376 - match Jsont_pointer.parent p with 377 - | Some parent -> Printf.printf "Some(%s)\n" (Jsont_pointer.to_string parent) 378 | None -> Printf.printf "None\n" 379 with Jsont.Error e -> 380 Printf.printf "ERROR: %s\n" (Jsont.Error.to_string e) ··· 382 (* Test: last *) 383 let test_last pointer_str = 384 try 385 - let p = Jsont_pointer.of_string_nav pointer_str in 386 - match Jsont_pointer.last p with 387 - | Some idx -> Format.printf "Some(%a)\n" Jsont_pointer.pp_index idx 388 | None -> Printf.printf "None\n" 389 with Jsont.Error e -> 390 Printf.printf "ERROR: %s\n" (Jsont.Error.to_string e) ··· 392 (* Test: indices *) 393 let test_indices pointer_str = 394 try 395 - let p = Jsont_pointer.of_string pointer_str in 396 let indices = indices_of_any p in 397 let strs = List.map (fun idx -> 398 match idx with ··· 406 (* Test: coercion - to_nav, to_nav_exn *) 407 let test_to_nav pointer_str = 408 try 409 - let p = Jsont_pointer.of_string pointer_str in 410 - match Jsont_pointer.to_nav p with 411 - | Some nav -> Printf.printf "Some(%s)\n" (Jsont_pointer.to_string nav) 412 | None -> Printf.printf "None\n" 413 with Jsont.Error e -> 414 Printf.printf "ERROR: %s\n" (Jsont.Error.to_string e) 415 416 let test_to_nav_exn pointer_str = 417 try 418 - let p = Jsont_pointer.of_string pointer_str in 419 - let nav = Jsont_pointer.to_nav_exn p in 420 - Printf.printf "OK: %s\n" (Jsont_pointer.to_string nav) 421 with Jsont.Error e -> 422 Printf.printf "ERROR: %s\n" (Jsont.Error.to_string e) 423 424 (* Test: of_string_kind *) 425 let test_of_string_kind pointer_str = 426 try 427 - match Jsont_pointer.of_string_kind pointer_str with 428 - | `Nav p -> Printf.printf "Nav(%s)\n" (Jsont_pointer.to_string p) 429 - | `Append p -> Printf.printf "Append(%s)\n" (Jsont_pointer.to_string p) 430 with Jsont.Error e -> 431 Printf.printf "ERROR: %s\n" (Jsont.Error.to_string e) 432 433 (* Test: of_string_result *) 434 let test_of_string_result pointer_str = 435 - match Jsont_pointer.of_string_result pointer_str with 436 | Ok p -> Printf.printf "Ok(%s)\n" (to_string_of_any p) 437 | Error e -> Printf.printf "Error(%s)\n" e 438 439 (* Test: of_uri_fragment_nav *) 440 let test_of_uri_fragment_nav frag = 441 try 442 - let p = Jsont_pointer.of_uri_fragment_nav frag in 443 - Printf.printf "OK: %s\n" (Jsont_pointer.to_string p) 444 with Jsont.Error e -> 445 Printf.printf "ERROR: %s\n" (Jsont.Error.to_string e) 446 447 (* Test: of_uri_fragment_result *) 448 let test_of_uri_fragment_result frag = 449 - match Jsont_pointer.of_uri_fragment_result frag with 450 | Ok p -> Printf.printf "Ok(%s)\n" (to_string_of_any p) 451 | Error e -> Printf.printf "Error(%s)\n" e 452 453 (* Test: pp and pp_verbose *) 454 let test_pp pointer_str = 455 try 456 - let p = Jsont_pointer.of_string pointer_str in 457 - let (Jsont_pointer.Any ptr) = p in 458 - Format.printf "%a\n" Jsont_pointer.pp ptr 459 with Jsont.Error e -> 460 Printf.printf "ERROR: %s\n" (Jsont.Error.to_string e) 461 462 let test_pp_verbose pointer_str = 463 try 464 - let p = Jsont_pointer.of_string pointer_str in 465 - let (Jsont_pointer.Any ptr) = p in 466 - Format.printf "%a\n" Jsont_pointer.pp_verbose ptr 467 with Jsont.Error e -> 468 Printf.printf "ERROR: %s\n" (Jsont.Error.to_string e) 469 470 (* Test: equal *) 471 let test_equal p1_str p2_str = 472 try 473 - let p1 = Jsont_pointer.of_string p1_str in 474 - let p2 = Jsont_pointer.of_string p2_str in 475 - let (Jsont_pointer.Any ptr1) = p1 in 476 - let (Jsont_pointer.Any ptr2) = p2 in 477 - Printf.printf "%b\n" (Jsont_pointer.equal ptr1 ptr2) 478 with Jsont.Error e -> 479 Printf.printf "ERROR: %s\n" (Jsont.Error.to_string e) 480 481 (* Test: compare *) 482 let test_compare p1_str p2_str = 483 try 484 - let p1 = Jsont_pointer.of_string p1_str in 485 - let p2 = Jsont_pointer.of_string p2_str in 486 - let (Jsont_pointer.Any ptr1) = p1 in 487 - let (Jsont_pointer.Any ptr2) = p2 in 488 - let cmp = Jsont_pointer.compare ptr1 ptr2 in 489 if cmp < 0 then Printf.printf "LT\n" 490 else if cmp > 0 then Printf.printf "GT\n" 491 else Printf.printf "EQ\n" ··· 501 |> Jsont.Path.mem "foo" 502 |> Jsont.Path.nth 1 503 ) in 504 - let p = Jsont_pointer.of_path path in 505 - Printf.printf "%s\n" (Jsont_pointer.to_string p) 506 507 let test_to_path pointer_str = 508 try 509 - let p = Jsont_pointer.of_string_nav pointer_str in 510 - let path = Jsont_pointer.to_path p in 511 (* Use rev_indices to get the indices in reverse order *) 512 let indices = Jsont.Path.rev_indices path in 513 let parts = List.rev_map (fun idx -> ··· 523 let test_get_result json_str pointer_str = 524 try 525 let json = parse_json json_str in 526 - let p = Jsont_pointer.of_string_nav pointer_str in 527 - match Jsont_pointer.get_result p json with 528 | Ok result -> Printf.printf "Ok(%s)\n" (json_to_string result) 529 | Error e -> Printf.printf "Error(%s)\n" (Jsont.Error.to_string e) 530 with Jsont.Error e -> ··· 535 try 536 let json = parse_json json_str in 537 let value = parse_json value_str in 538 - let p = Jsont_pointer.of_string pointer_str in 539 - let result = Jsont_pointer.set p json ~value in 540 Printf.printf "%s\n" (json_to_string result) 541 with Jsont.Error e -> 542 Printf.printf "ERROR: %s\n" (Jsont.Error.to_string e) ··· 545 let test_jsont_codec pointer_str = 546 try 547 let json = Jsont.Json.string pointer_str in 548 - let decoded = match Jsont.Json.decode' Jsont_pointer.jsont json with 549 | Ok p -> p 550 | Error e -> raise (Jsont.Error e) 551 in 552 - let encoded = match Jsont.Json.encode' Jsont_pointer.jsont decoded with 553 | Ok j -> j 554 | Error e -> raise (Jsont.Error e) 555 in ··· 562 let test_jsont_kind pointer_str = 563 try 564 let json = Jsont.Json.string pointer_str in 565 - let decoded = match Jsont.Json.decode' Jsont_pointer.jsont_kind json with 566 | Ok p -> p 567 | Error e -> raise (Jsont.Error e) 568 in 569 match decoded with 570 - | `Nav p -> Printf.printf "Nav(%s)\n" (Jsont_pointer.to_string p) 571 - | `Append p -> Printf.printf "Append(%s)\n" (Jsont_pointer.to_string p) 572 with Jsont.Error e -> 573 Printf.printf "ERROR: %s\n" (Jsont.Error.to_string e) 574 ··· 576 let test_jsont_nav pointer_str = 577 try 578 let json = Jsont.Json.string pointer_str in 579 - let decoded = match Jsont.Json.decode' Jsont_pointer.jsont_nav json with 580 | Ok p -> p 581 | Error e -> raise (Jsont.Error e) 582 in 583 - Printf.printf "OK: %s\n" (Jsont_pointer.to_string decoded) 584 with Jsont.Error e -> 585 Printf.printf "ERROR: %s\n" (Jsont.Error.to_string e) 586 ··· 588 let test_jsont_uri_fragment pointer_str = 589 try 590 (* First parse it normally, then encode as URI fragment *) 591 - let p = Jsont_pointer.of_string pointer_str in 592 - let encoded = match Jsont.Json.encode' Jsont_pointer.jsont_uri_fragment p with 593 | Ok j -> j 594 | Error e -> raise (Jsont.Error e) 595 in ··· 602 let test_query_path json_str pointer_str = 603 try 604 let json = parse_json json_str in 605 - let p = Jsont_pointer.of_string_nav pointer_str in 606 - let codec = Jsont_pointer.path p Jsont.string in 607 let result = match Jsont.Json.decode' codec json with 608 | Ok v -> v 609 | Error e -> raise (Jsont.Error e) ··· 616 let test_query_path_absent json_str pointer_str default = 617 try 618 let json = parse_json json_str in 619 - let p = Jsont_pointer.of_string_nav pointer_str in 620 - let codec = Jsont_pointer.path ~absent:default p Jsont.string in 621 let result = match Jsont.Json.decode' codec json with 622 | Ok v -> v 623 | Error e -> raise (Jsont.Error e) ··· 630 let test_set_path json_str pointer_str value_str = 631 try 632 let json = parse_json json_str in 633 - let p = Jsont_pointer.of_string pointer_str in 634 - let codec = Jsont_pointer.set_path Jsont.string p value_str in 635 let result = match Jsont.Json.recode' codec json with 636 | Ok v -> v 637 | Error e -> raise (Jsont.Error e) ··· 644 let test_update_path json_str pointer_str = 645 try 646 let json = parse_json json_str in 647 - let p = Jsont_pointer.of_string_nav pointer_str in 648 - let codec = Jsont_pointer.update_path p Jsont.string in 649 let result = match Jsont.Json.recode' codec json with 650 | Ok v -> v 651 | Error e -> raise (Jsont.Error e) ··· 658 let test_delete_path json_str pointer_str = 659 try 660 let json = parse_json json_str in 661 - let p = Jsont_pointer.of_string_nav pointer_str in 662 - let codec = Jsont_pointer.delete_path p in 663 let result = match Jsont.Json.recode' codec json with 664 | Ok v -> v 665 | Error e -> raise (Jsont.Error e) ··· 672 let test_delete_path_absent json_str pointer_str = 673 try 674 let json = parse_json json_str in 675 - let p = Jsont_pointer.of_string_nav pointer_str in 676 - let codec = Jsont_pointer.delete_path ~allow_absent:true p in 677 let result = match Jsont.Json.recode' codec json with 678 | Ok v -> v 679 | Error e -> raise (Jsont.Error e) ··· 684 685 (* Test: JMAP of_string_result *) 686 let test_jmap_of_string_result pointer_str = 687 - match Jsont_pointer.Jmap.of_string_result pointer_str with 688 - | Ok p -> Printf.printf "Ok(%s)\n" (Jsont_pointer.Jmap.to_string p) 689 | Error e -> Printf.printf "Error(%s)\n" e 690 691 (* Test: JMAP pp *) 692 let test_jmap_pp pointer_str = 693 try 694 - let p = Jsont_pointer.Jmap.of_string pointer_str in 695 - Format.printf "%a\n" Jsont_pointer.Jmap.pp p 696 with Jsont.Error e -> 697 Printf.printf "ERROR: %s\n" (Jsont.Error.to_string e) 698 ··· 700 let test_jmap_eval_result json_str pointer_str = 701 try 702 let json = parse_json json_str in 703 - let p = Jsont_pointer.Jmap.of_string pointer_str in 704 - match Jsont_pointer.Jmap.eval_result p json with 705 | Ok result -> Printf.printf "Ok(%s)\n" (json_to_string result) 706 | Error e -> Printf.printf "Error(%s)\n" (Jsont.Error.to_string e) 707 with Jsont.Error e -> ··· 711 let test_jmap_find json_str pointer_str = 712 try 713 let json = parse_json json_str in 714 - let p = Jsont_pointer.Jmap.of_string pointer_str in 715 - match Jsont_pointer.Jmap.find p json with 716 | Some result -> Printf.printf "Some(%s)\n" (json_to_string result) 717 | None -> Printf.printf "None\n" 718 with Jsont.Error e -> ··· 722 let test_jmap_jsont pointer_str = 723 try 724 let json = Jsont.Json.string pointer_str in 725 - let decoded = match Jsont.Json.decode' Jsont_pointer.Jmap.jsont json with 726 | Ok p -> p 727 | Error e -> raise (Jsont.Error e) 728 in 729 - let encoded = match Jsont.Json.encode' Jsont_pointer.Jmap.jsont decoded with 730 | Ok j -> j 731 | Error e -> raise (Jsont.Error e) 732 in
··· 1 + (* Test runner for json_pointer *) 2 3 let read_file path = 4 let ic = open_in path in ··· 18 | Error e -> failwith e 19 20 (* Helper to get indices from any pointer *) 21 + let indices_of_any (Json_pointer.Any p) = Json_pointer.indices p 22 23 (* Helper to convert to string from any pointer *) 24 + let to_string_of_any (Json_pointer.Any p) = Json_pointer.to_string p 25 26 (* Helper to check if pointer is append *) 27 + let is_append_any p = not (Json_pointer.is_nav p) 28 29 (* Test: parse pointer and print indices *) 30 let test_parse pointer_str = 31 try 32 + let result = Json_pointer.of_string pointer_str in 33 let indices = indices_of_any result in 34 let index_strs = List.map (fun idx -> 35 match idx with ··· 44 (* Test: roundtrip pointer string *) 45 let test_roundtrip pointer_str = 46 try 47 + let result = Json_pointer.of_string pointer_str in 48 let s = to_string_of_any result in 49 if s = pointer_str then 50 Printf.printf "OK: %s\n" s ··· 57 let test_eval json_path pointer_str = 58 try 59 let json = parse_json (read_file json_path) in 60 + let p = Json_pointer.of_string_nav pointer_str in 61 + let result = Json_pointer.get p json in 62 Printf.printf "OK: %s\n" (json_to_string result) 63 with 64 | Jsont.Error e -> ··· 68 69 (* Test: escape token *) 70 let test_escape token = 71 + let escaped = Json_pointer.Token.escape token in 72 Printf.printf "%s\n" escaped 73 74 (* Test: unescape token *) 75 let test_unescape token = 76 try 77 + let unescaped = Json_pointer.Token.unescape token in 78 Printf.printf "OK: %s\n" unescaped 79 with Jsont.Error e -> 80 Printf.printf "ERROR: %s\n" (Jsont.Error.to_string e) ··· 82 (* Test: URI fragment roundtrip *) 83 let test_uri_fragment pointer_str = 84 try 85 + let result = Json_pointer.of_string pointer_str in 86 + let (Json_pointer.Any p) = result in 87 + let frag = Json_pointer.to_uri_fragment p in 88 + let result2 = Json_pointer.of_uri_fragment frag in 89 let s2 = to_string_of_any result2 in 90 if s2 = pointer_str then 91 Printf.printf "OK: %s -> %s\n" pointer_str frag ··· 99 try 100 let json = parse_json json_str in 101 let value = parse_json value_str in 102 + let p = Json_pointer.of_string pointer_str in 103 + let result = Json_pointer.add p json ~value in 104 Printf.printf "%s\n" (json_to_string result) 105 with Jsont.Error e -> 106 Printf.printf "ERROR: %s\n" (Jsont.Error.to_string e) ··· 109 let test_remove json_str pointer_str = 110 try 111 let json = parse_json json_str in 112 + let p = Json_pointer.of_string_nav pointer_str in 113 + let result = Json_pointer.remove p json in 114 Printf.printf "%s\n" (json_to_string result) 115 with Jsont.Error e -> 116 Printf.printf "ERROR: %s\n" (Jsont.Error.to_string e) ··· 119 let test_replace json_str pointer_str value_str = 120 try 121 let json = parse_json json_str in 122 + let p = Json_pointer.of_string_nav pointer_str in 123 let value = parse_json value_str in 124 + let result = Json_pointer.replace p json ~value in 125 Printf.printf "%s\n" (json_to_string result) 126 with Jsont.Error e -> 127 Printf.printf "ERROR: %s\n" (Jsont.Error.to_string e) ··· 130 let test_move json_str from_str path_str = 131 try 132 let json = parse_json json_str in 133 + let from = Json_pointer.of_string_nav from_str in 134 + let path = Json_pointer.of_string path_str in 135 + let result = Json_pointer.move ~from ~path json in 136 Printf.printf "%s\n" (json_to_string result) 137 with Jsont.Error e -> 138 Printf.printf "ERROR: %s\n" (Jsont.Error.to_string e) ··· 141 let test_copy json_str from_str path_str = 142 try 143 let json = parse_json json_str in 144 + let from = Json_pointer.of_string_nav from_str in 145 + let path = Json_pointer.of_string path_str in 146 + let result = Json_pointer.copy ~from ~path json in 147 Printf.printf "%s\n" (json_to_string result) 148 with Jsont.Error e -> 149 Printf.printf "ERROR: %s\n" (Jsont.Error.to_string e) ··· 152 let test_test json_str pointer_str expected_str = 153 try 154 let json = parse_json json_str in 155 + let p = Json_pointer.of_string_nav pointer_str in 156 let expected = parse_json expected_str in 157 + let result = Json_pointer.test p json ~expected in 158 Printf.printf "%b\n" result 159 with Jsont.Error e -> 160 Printf.printf "ERROR: %s\n" (Jsont.Error.to_string e) ··· 163 let test_has json_str pointer_str = 164 try 165 let json = parse_json json_str in 166 + let p = Json_pointer.of_string_nav pointer_str in 167 + let result = Json_pointer.find p json in 168 Printf.printf "%b\n" (Option.is_some result) 169 with Jsont.Error e -> 170 Printf.printf "ERROR: %s\n" (Jsont.Error.to_string e) ··· 172 (* Test: JMAP extended pointer parse *) 173 let test_jmap_parse pointer_str = 174 try 175 + let p = Json_pointer.Jmap.of_string pointer_str in 176 + let s = Json_pointer.Jmap.to_string p in 177 if s = "" then Printf.printf "OK: (root)\n" 178 else Printf.printf "OK: %s\n" s 179 with Jsont.Error e -> ··· 183 let test_jmap_eval json_str pointer_str = 184 try 185 let json = parse_json json_str in 186 + let p = Json_pointer.Jmap.of_string pointer_str in 187 + let result = Json_pointer.Jmap.eval p json in 188 Printf.printf "OK: %s\n" (json_to_string result) 189 with 190 | Jsont.Error e -> ··· 196 let test_jmap_eval_file json_path pointer_str = 197 try 198 let json = parse_json (read_file json_path) in 199 + let p = Json_pointer.Jmap.of_string pointer_str in 200 + let result = Json_pointer.Jmap.eval p json in 201 Printf.printf "OK: %s\n" (json_to_string result) 202 with 203 | Jsont.Error e -> ··· 209 let test_jmap_path_strings json_str pointer_str = 210 try 211 let json = parse_json json_str in 212 + let p = Json_pointer.Jmap.of_string pointer_str in 213 + let codec = Json_pointer.Jmap.path_list p Jsont.string in 214 let result = match Jsont.Json.decode' codec json with 215 | Ok v -> v 216 | Error e -> raise (Jsont.Error e) ··· 226 let test_jmap_path_ints json_str pointer_str = 227 try 228 let json = parse_json json_str in 229 + let p = Json_pointer.Jmap.of_string pointer_str in 230 + let codec = Json_pointer.Jmap.path_list p Jsont.int in 231 let result = match Jsont.Json.decode' codec json with 232 | Ok v -> v 233 | Error e -> raise (Jsont.Error e) ··· 243 let test_jmap_path_single json_str pointer_str = 244 try 245 let json = parse_json json_str in 246 + let p = Json_pointer.Jmap.of_string pointer_str in 247 + let codec = Json_pointer.Jmap.path p Jsont.string in 248 let result = match Jsont.Json.decode' codec json with 249 | Ok v -> v 250 | Error e -> raise (Jsont.Error e) ··· 260 let test_jmap_path_absent json_str pointer_str default = 261 try 262 let json = parse_json json_str in 263 + let p = Json_pointer.Jmap.of_string pointer_str in 264 + let codec = Json_pointer.Jmap.path ~absent:default p Jsont.string in 265 let result = match Jsont.Json.decode' codec json with 266 | Ok v -> v 267 | Error e -> raise (Jsont.Error e) ··· 275 276 (* Test: index functions - mem, nth, pp_index, equal_index, compare_index *) 277 let test_mem name = 278 + let idx = Json_pointer.mem name in 279 + Format.printf "mem(%s) = %a\n" name Json_pointer.pp_index idx 280 281 let test_nth n = 282 + let idx = Json_pointer.nth n in 283 + Format.printf "nth(%d) = %a\n" n Json_pointer.pp_index idx 284 285 let test_equal_index idx1_str idx2_str = 286 let parse_idx s = 287 if String.length s > 0 && s.[0] >= '0' && s.[0] <= '9' then 288 + Json_pointer.nth (int_of_string s) 289 else 290 + Json_pointer.mem s 291 in 292 let idx1 = parse_idx idx1_str in 293 let idx2 = parse_idx idx2_str in 294 + Printf.printf "%b\n" (Json_pointer.equal_index idx1 idx2) 295 296 let test_compare_index idx1_str idx2_str = 297 let parse_idx s = 298 if String.length s > 0 && s.[0] >= '0' && s.[0] <= '9' then 299 + Json_pointer.nth (int_of_string s) 300 else 301 + Json_pointer.mem s 302 in 303 let idx1 = parse_idx idx1_str in 304 let idx2 = parse_idx idx2_str in 305 + let cmp = Json_pointer.compare_index idx1 idx2 in 306 if cmp < 0 then Printf.printf "LT\n" 307 else if cmp > 0 then Printf.printf "GT\n" 308 else Printf.printf "EQ\n" 309 310 (* Test: pointer constructors - root, is_root, make *) 311 let test_root () = 312 + let r = Json_pointer.root in 313 + Printf.printf "root = %s\n" (Json_pointer.to_string r); 314 + Printf.printf "is_root(root) = %b\n" (Json_pointer.is_root r) 315 316 let test_is_root pointer_str = 317 try 318 + let p = Json_pointer.of_string pointer_str in 319 + let (Json_pointer.Any ptr) = p in 320 + Printf.printf "%b\n" (Json_pointer.is_root ptr) 321 with Jsont.Error e -> 322 Printf.printf "ERROR: %s\n" (Jsont.Error.to_string e) 323 ··· 326 let parts = String.split_on_char ',' indices_str in 327 let indices = List.map (fun s -> 328 let s = String.trim s in 329 + if s = "" then Json_pointer.mem "" 330 else if String.length s > 0 && s.[0] >= '0' && s.[0] <= '9' then 331 + Json_pointer.nth (int_of_string s) 332 else 333 + Json_pointer.mem s 334 ) parts in 335 + let p = Json_pointer.make indices in 336 + Printf.printf "%s\n" (Json_pointer.to_string p) 337 338 (* Test: append_index and / operator *) 339 let test_append_index base_str index_str = 340 try 341 + let base = Json_pointer.of_string_nav base_str in 342 let idx = 343 if String.length index_str > 0 && index_str.[0] >= '0' && index_str.[0] <= '9' then 344 + Json_pointer.nth (int_of_string index_str) 345 else 346 + Json_pointer.mem index_str 347 in 348 + let result = Json_pointer.(base / idx) in 349 + Printf.printf "%s\n" (Json_pointer.to_string result) 350 with Jsont.Error e -> 351 Printf.printf "ERROR: %s\n" (Jsont.Error.to_string e) 352 353 (* Test: at_end *) 354 let test_at_end pointer_str = 355 try 356 + let p = Json_pointer.of_string_nav pointer_str in 357 + let append_p = Json_pointer.at_end p in 358 + Printf.printf "%s\n" (Json_pointer.to_string append_p) 359 with Jsont.Error e -> 360 Printf.printf "ERROR: %s\n" (Jsont.Error.to_string e) 361 362 (* Test: concat *) 363 let test_concat p1_str p2_str = 364 try 365 + let p1 = Json_pointer.of_string_nav p1_str in 366 + let p2 = Json_pointer.of_string_nav p2_str in 367 + let result = Json_pointer.concat p1 p2 in 368 + Printf.printf "%s\n" (Json_pointer.to_string result) 369 with Jsont.Error e -> 370 Printf.printf "ERROR: %s\n" (Jsont.Error.to_string e) 371 372 (* Test: parent *) 373 let test_parent pointer_str = 374 try 375 + let p = Json_pointer.of_string_nav pointer_str in 376 + match Json_pointer.parent p with 377 + | Some parent -> Printf.printf "Some(%s)\n" (Json_pointer.to_string parent) 378 | None -> Printf.printf "None\n" 379 with Jsont.Error e -> 380 Printf.printf "ERROR: %s\n" (Jsont.Error.to_string e) ··· 382 (* Test: last *) 383 let test_last pointer_str = 384 try 385 + let p = Json_pointer.of_string_nav pointer_str in 386 + match Json_pointer.last p with 387 + | Some idx -> Format.printf "Some(%a)\n" Json_pointer.pp_index idx 388 | None -> Printf.printf "None\n" 389 with Jsont.Error e -> 390 Printf.printf "ERROR: %s\n" (Jsont.Error.to_string e) ··· 392 (* Test: indices *) 393 let test_indices pointer_str = 394 try 395 + let p = Json_pointer.of_string pointer_str in 396 let indices = indices_of_any p in 397 let strs = List.map (fun idx -> 398 match idx with ··· 406 (* Test: coercion - to_nav, to_nav_exn *) 407 let test_to_nav pointer_str = 408 try 409 + let p = Json_pointer.of_string pointer_str in 410 + match Json_pointer.to_nav p with 411 + | Some nav -> Printf.printf "Some(%s)\n" (Json_pointer.to_string nav) 412 | None -> Printf.printf "None\n" 413 with Jsont.Error e -> 414 Printf.printf "ERROR: %s\n" (Jsont.Error.to_string e) 415 416 let test_to_nav_exn pointer_str = 417 try 418 + let p = Json_pointer.of_string pointer_str in 419 + let nav = Json_pointer.to_nav_exn p in 420 + Printf.printf "OK: %s\n" (Json_pointer.to_string nav) 421 with Jsont.Error e -> 422 Printf.printf "ERROR: %s\n" (Jsont.Error.to_string e) 423 424 (* Test: of_string_kind *) 425 let test_of_string_kind pointer_str = 426 try 427 + match Json_pointer.of_string_kind pointer_str with 428 + | `Nav p -> Printf.printf "Nav(%s)\n" (Json_pointer.to_string p) 429 + | `Append p -> Printf.printf "Append(%s)\n" (Json_pointer.to_string p) 430 with Jsont.Error e -> 431 Printf.printf "ERROR: %s\n" (Jsont.Error.to_string e) 432 433 (* Test: of_string_result *) 434 let test_of_string_result pointer_str = 435 + match Json_pointer.of_string_result pointer_str with 436 | Ok p -> Printf.printf "Ok(%s)\n" (to_string_of_any p) 437 | Error e -> Printf.printf "Error(%s)\n" e 438 439 (* Test: of_uri_fragment_nav *) 440 let test_of_uri_fragment_nav frag = 441 try 442 + let p = Json_pointer.of_uri_fragment_nav frag in 443 + Printf.printf "OK: %s\n" (Json_pointer.to_string p) 444 with Jsont.Error e -> 445 Printf.printf "ERROR: %s\n" (Jsont.Error.to_string e) 446 447 (* Test: of_uri_fragment_result *) 448 let test_of_uri_fragment_result frag = 449 + match Json_pointer.of_uri_fragment_result frag with 450 | Ok p -> Printf.printf "Ok(%s)\n" (to_string_of_any p) 451 | Error e -> Printf.printf "Error(%s)\n" e 452 453 (* Test: pp and pp_verbose *) 454 let test_pp pointer_str = 455 try 456 + let p = Json_pointer.of_string pointer_str in 457 + let (Json_pointer.Any ptr) = p in 458 + Format.printf "%a\n" Json_pointer.pp ptr 459 with Jsont.Error e -> 460 Printf.printf "ERROR: %s\n" (Jsont.Error.to_string e) 461 462 let test_pp_verbose pointer_str = 463 try 464 + let p = Json_pointer.of_string pointer_str in 465 + let (Json_pointer.Any ptr) = p in 466 + Format.printf "%a\n" Json_pointer.pp_verbose ptr 467 with Jsont.Error e -> 468 Printf.printf "ERROR: %s\n" (Jsont.Error.to_string e) 469 470 (* Test: equal *) 471 let test_equal p1_str p2_str = 472 try 473 + let p1 = Json_pointer.of_string p1_str in 474 + let p2 = Json_pointer.of_string p2_str in 475 + let (Json_pointer.Any ptr1) = p1 in 476 + let (Json_pointer.Any ptr2) = p2 in 477 + Printf.printf "%b\n" (Json_pointer.equal ptr1 ptr2) 478 with Jsont.Error e -> 479 Printf.printf "ERROR: %s\n" (Jsont.Error.to_string e) 480 481 (* Test: compare *) 482 let test_compare p1_str p2_str = 483 try 484 + let p1 = Json_pointer.of_string p1_str in 485 + let p2 = Json_pointer.of_string p2_str in 486 + let (Json_pointer.Any ptr1) = p1 in 487 + let (Json_pointer.Any ptr2) = p2 in 488 + let cmp = Json_pointer.compare ptr1 ptr2 in 489 if cmp < 0 then Printf.printf "LT\n" 490 else if cmp > 0 then Printf.printf "GT\n" 491 else Printf.printf "EQ\n" ··· 501 |> Jsont.Path.mem "foo" 502 |> Jsont.Path.nth 1 503 ) in 504 + let p = Json_pointer.of_path path in 505 + Printf.printf "%s\n" (Json_pointer.to_string p) 506 507 let test_to_path pointer_str = 508 try 509 + let p = Json_pointer.of_string_nav pointer_str in 510 + let path = Json_pointer.to_path p in 511 (* Use rev_indices to get the indices in reverse order *) 512 let indices = Jsont.Path.rev_indices path in 513 let parts = List.rev_map (fun idx -> ··· 523 let test_get_result json_str pointer_str = 524 try 525 let json = parse_json json_str in 526 + let p = Json_pointer.of_string_nav pointer_str in 527 + match Json_pointer.get_result p json with 528 | Ok result -> Printf.printf "Ok(%s)\n" (json_to_string result) 529 | Error e -> Printf.printf "Error(%s)\n" (Jsont.Error.to_string e) 530 with Jsont.Error e -> ··· 535 try 536 let json = parse_json json_str in 537 let value = parse_json value_str in 538 + let p = Json_pointer.of_string pointer_str in 539 + let result = Json_pointer.set p json ~value in 540 Printf.printf "%s\n" (json_to_string result) 541 with Jsont.Error e -> 542 Printf.printf "ERROR: %s\n" (Jsont.Error.to_string e) ··· 545 let test_jsont_codec pointer_str = 546 try 547 let json = Jsont.Json.string pointer_str in 548 + let decoded = match Jsont.Json.decode' Json_pointer.jsont json with 549 | Ok p -> p 550 | Error e -> raise (Jsont.Error e) 551 in 552 + let encoded = match Jsont.Json.encode' Json_pointer.jsont decoded with 553 | Ok j -> j 554 | Error e -> raise (Jsont.Error e) 555 in ··· 562 let test_jsont_kind pointer_str = 563 try 564 let json = Jsont.Json.string pointer_str in 565 + let decoded = match Jsont.Json.decode' Json_pointer.jsont_kind json with 566 | Ok p -> p 567 | Error e -> raise (Jsont.Error e) 568 in 569 match decoded with 570 + | `Nav p -> Printf.printf "Nav(%s)\n" (Json_pointer.to_string p) 571 + | `Append p -> Printf.printf "Append(%s)\n" (Json_pointer.to_string p) 572 with Jsont.Error e -> 573 Printf.printf "ERROR: %s\n" (Jsont.Error.to_string e) 574 ··· 576 let test_jsont_nav pointer_str = 577 try 578 let json = Jsont.Json.string pointer_str in 579 + let decoded = match Jsont.Json.decode' Json_pointer.jsont_nav json with 580 | Ok p -> p 581 | Error e -> raise (Jsont.Error e) 582 in 583 + Printf.printf "OK: %s\n" (Json_pointer.to_string decoded) 584 with Jsont.Error e -> 585 Printf.printf "ERROR: %s\n" (Jsont.Error.to_string e) 586 ··· 588 let test_jsont_uri_fragment pointer_str = 589 try 590 (* First parse it normally, then encode as URI fragment *) 591 + let p = Json_pointer.of_string pointer_str in 592 + let encoded = match Jsont.Json.encode' Json_pointer.jsont_uri_fragment p with 593 | Ok j -> j 594 | Error e -> raise (Jsont.Error e) 595 in ··· 602 let test_query_path json_str pointer_str = 603 try 604 let json = parse_json json_str in 605 + let p = Json_pointer.of_string_nav pointer_str in 606 + let codec = Json_pointer.path p Jsont.string in 607 let result = match Jsont.Json.decode' codec json with 608 | Ok v -> v 609 | Error e -> raise (Jsont.Error e) ··· 616 let test_query_path_absent json_str pointer_str default = 617 try 618 let json = parse_json json_str in 619 + let p = Json_pointer.of_string_nav pointer_str in 620 + let codec = Json_pointer.path ~absent:default p Jsont.string in 621 let result = match Jsont.Json.decode' codec json with 622 | Ok v -> v 623 | Error e -> raise (Jsont.Error e) ··· 630 let test_set_path json_str pointer_str value_str = 631 try 632 let json = parse_json json_str in 633 + let p = Json_pointer.of_string pointer_str in 634 + let codec = Json_pointer.set_path Jsont.string p value_str in 635 let result = match Jsont.Json.recode' codec json with 636 | Ok v -> v 637 | Error e -> raise (Jsont.Error e) ··· 644 let test_update_path json_str pointer_str = 645 try 646 let json = parse_json json_str in 647 + let p = Json_pointer.of_string_nav pointer_str in 648 + let codec = Json_pointer.update_path p Jsont.string in 649 let result = match Jsont.Json.recode' codec json with 650 | Ok v -> v 651 | Error e -> raise (Jsont.Error e) ··· 658 let test_delete_path json_str pointer_str = 659 try 660 let json = parse_json json_str in 661 + let p = Json_pointer.of_string_nav pointer_str in 662 + let codec = Json_pointer.delete_path p in 663 let result = match Jsont.Json.recode' codec json with 664 | Ok v -> v 665 | Error e -> raise (Jsont.Error e) ··· 672 let test_delete_path_absent json_str pointer_str = 673 try 674 let json = parse_json json_str in 675 + let p = Json_pointer.of_string_nav pointer_str in 676 + let codec = Json_pointer.delete_path ~allow_absent:true p in 677 let result = match Jsont.Json.recode' codec json with 678 | Ok v -> v 679 | Error e -> raise (Jsont.Error e) ··· 684 685 (* Test: JMAP of_string_result *) 686 let test_jmap_of_string_result pointer_str = 687 + match Json_pointer.Jmap.of_string_result pointer_str with 688 + | Ok p -> Printf.printf "Ok(%s)\n" (Json_pointer.Jmap.to_string p) 689 | Error e -> Printf.printf "Error(%s)\n" e 690 691 (* Test: JMAP pp *) 692 let test_jmap_pp pointer_str = 693 try 694 + let p = Json_pointer.Jmap.of_string pointer_str in 695 + Format.printf "%a\n" Json_pointer.Jmap.pp p 696 with Jsont.Error e -> 697 Printf.printf "ERROR: %s\n" (Jsont.Error.to_string e) 698 ··· 700 let test_jmap_eval_result json_str pointer_str = 701 try 702 let json = parse_json json_str in 703 + let p = Json_pointer.Jmap.of_string pointer_str in 704 + match Json_pointer.Jmap.eval_result p json with 705 | Ok result -> Printf.printf "Ok(%s)\n" (json_to_string result) 706 | Error e -> Printf.printf "Error(%s)\n" (Jsont.Error.to_string e) 707 with Jsont.Error e -> ··· 711 let test_jmap_find json_str pointer_str = 712 try 713 let json = parse_json json_str in 714 + let p = Json_pointer.Jmap.of_string pointer_str in 715 + match Json_pointer.Jmap.find p json with 716 | Some result -> Printf.printf "Some(%s)\n" (json_to_string result) 717 | None -> Printf.printf "None\n" 718 with Jsont.Error e -> ··· 722 let test_jmap_jsont pointer_str = 723 try 724 let json = Jsont.Json.string pointer_str in 725 + let decoded = match Jsont.Json.decode' Json_pointer.Jmap.jsont json with 726 | Ok p -> p 727 | Error e -> raise (Jsont.Error e) 728 in 729 + let encoded = match Jsont.Json.encode' Json_pointer.Jmap.jsont decoded with 730 | Ok j -> j 731 | Error e -> raise (Jsont.Error e) 732 in