My agentic slop goes here. Not intended for anyone else!
at main 3.5 kB view raw
1(** JMAP Request Object 2 3 A Request object represents a single HTTP POST to the JMAP API endpoint. 4 It contains capabilities the client wants to use and a list of method calls. 5 6 Reference: RFC 8620 Section 3.3 7 Test files: 8 - test/data/core/request_echo.json 9 - test/data/core/request_get.json 10 - All request_*.json files 11*) 12 13(** Main request type *) 14type t = { 15 using : Jmap_capability.t list; 16 method_calls : Jmap_invocation.invocation_list; 17 created_ids : (Jmap_id.t * Jmap_id.t) list option; 18} 19 20(** Accessors *) 21let using t = t.using 22let method_calls t = t.method_calls 23let created_ids t = t.created_ids 24 25(** Create a request *) 26let make ?(created_ids=None) ~using method_calls = 27 { using; method_calls; created_ids } 28 29(** Parser submodule *) 30module Parser = struct 31 (** Parse request from JSON value. 32 Test files: test/data/core/request_*.json *) 33 let of_json json = 34 match json with 35 | `O fields -> 36 let get_field name = 37 match List.assoc_opt name fields with 38 | Some v -> v 39 | None -> raise (Jmap_error.Parse_error (Printf.sprintf "Missing field: %s" name)) 40 in 41 42 (* Parse using *) 43 let using = 44 match get_field "using" with 45 | `A caps -> 46 List.map (function 47 | `String cap -> Jmap_capability.of_string cap 48 | _ -> raise (Jmap_error.Parse_error "using values must be strings") 49 ) caps 50 | _ -> raise (Jmap_error.Parse_error "using must be an array") 51 in 52 53 (* Parse methodCalls *) 54 let method_calls = 55 match get_field "methodCalls" with 56 | `A calls -> List.map Jmap_invocation.of_json calls 57 | _ -> raise (Jmap_error.Parse_error "methodCalls must be an array") 58 in 59 60 (* Parse createdIds (optional) *) 61 let created_ids = 62 match List.assoc_opt "createdIds" fields with 63 | Some (`O ids) -> 64 Some (List.map (fun (k, v) -> 65 match v with 66 | `String id -> (Jmap_id.of_string k, Jmap_id.of_string id) 67 | _ -> raise (Jmap_error.Parse_error "createdIds values must be strings") 68 ) ids) 69 | Some _ -> raise (Jmap_error.Parse_error "createdIds must be an object") 70 | None -> None 71 in 72 73 { using; method_calls; created_ids } 74 | _ -> raise (Jmap_error.Parse_error "Request must be a JSON object") 75 76 (** Parse request from JSON string *) 77 let of_string s = 78 try 79 of_json (Ezjsonm.from_string s) 80 with 81 | Ezjsonm.Parse_error (_, msg) -> 82 raise (Jmap_error.Parse_error ("Invalid JSON: " ^ msg)) 83 84 (** Parse request from input channel *) 85 let of_channel ic = 86 try 87 of_json (Ezjsonm.from_channel ic) 88 with 89 | Ezjsonm.Parse_error (_, msg) -> 90 raise (Jmap_error.Parse_error ("Invalid JSON: " ^ msg)) 91end 92 93(** Serialization *) 94let to_json t = 95 let using_json = `A (List.map (fun cap -> 96 `String (Jmap_capability.to_string cap) 97 ) t.using) in 98 99 let method_calls_json = `A (List.map (fun (Jmap_invocation.Packed inv) -> 100 Jmap_invocation.to_json inv 101 ) t.method_calls) in 102 103 let fields = [ 104 ("using", using_json); 105 ("methodCalls", method_calls_json); 106 ] in 107 108 let fields = match t.created_ids with 109 | Some ids -> 110 let ids_json = `O (List.map (fun (k, v) -> 111 (Jmap_id.to_string k, `String (Jmap_id.to_string v)) 112 ) ids) in 113 fields @ [("createdIds", ids_json)] 114 | None -> fields 115 in 116 117 `O fields