My agentic slop goes here. Not intended for anyone else!
1(** JMAP Response Object 2 3 A Response object is returned from the JMAP API endpoint in response to a Request. 4 It contains method responses and the current session state. 5 6 Reference: RFC 8620 Section 3.4 7 Test files: 8 - test/data/core/response_echo.json 9 - test/data/core/response_get.json 10 - All response_*.json files 11*) 12 13(** Main response type *) 14type t = { 15 method_responses : Jmap_invocation.response_list; 16 created_ids : (Jmap_id.t * Jmap_id.t) list option; 17 session_state : string; 18} 19 20(** Accessors *) 21let method_responses t = t.method_responses 22let created_ids t = t.created_ids 23let session_state t = t.session_state 24 25(** Create a response *) 26let make ?(created_ids=None) ~method_responses ~session_state () = 27 { method_responses; created_ids; session_state } 28 29(** Parser submodule *) 30module Parser = struct 31 (** Parse response from JSON value. 32 Test files: test/data/core/response_*.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 methodResponses - similar to parsing request methodCalls *) 43 let method_responses = 44 match get_field "methodResponses" with 45 | `A responses -> 46 List.map (fun resp_json -> 47 (* Each response is ["method", {...}, "callId"] *) 48 (* For now, just parse as generic invocations *) 49 match resp_json with 50 | `A [(`String method_name); response; (`String call_id)] -> 51 (* Parse as response invocation, storing raw JSON *) 52 Jmap_invocation.PackedResponse (Jmap_invocation.ResponseInvocation { 53 method_name; 54 response; 55 call_id; 56 witness = Jmap_invocation.Echo; 57 }) 58 | _ -> raise (Jmap_error.Parse_error "Invalid method response format") 59 ) responses 60 | _ -> raise (Jmap_error.Parse_error "methodResponses must be an array") 61 in 62 63 (* Parse createdIds (optional) *) 64 let created_ids = 65 match List.assoc_opt "createdIds" fields with 66 | Some (`O ids) -> 67 Some (List.map (fun (k, v) -> 68 match v with 69 | `String id -> (Jmap_id.of_string k, Jmap_id.of_string id) 70 | _ -> raise (Jmap_error.Parse_error "createdIds values must be strings") 71 ) ids) 72 | Some _ -> raise (Jmap_error.Parse_error "createdIds must be an object") 73 | None -> None 74 in 75 76 (* Parse sessionState *) 77 let session_state = 78 match get_field "sessionState" with 79 | `String s -> s 80 | _ -> raise (Jmap_error.Parse_error "sessionState must be a string") 81 in 82 83 { method_responses; created_ids; session_state } 84 | _ -> raise (Jmap_error.Parse_error "Response must be a JSON object") 85 86 (** Parse response from JSON string *) 87 let of_string s = 88 try 89 of_json (Ezjsonm.from_string s) 90 with 91 | Ezjsonm.Parse_error (_, msg) -> 92 raise (Jmap_error.Parse_error ("Invalid JSON: " ^ msg)) 93 94 (** Parse response from input channel *) 95 let of_channel ic = 96 try 97 of_json (Ezjsonm.from_channel ic) 98 with 99 | Ezjsonm.Parse_error (_, msg) -> 100 raise (Jmap_error.Parse_error ("Invalid JSON: " ^ msg)) 101end 102 103(** Serialization *) 104let to_json _t = 105 (* TODO: Implement JSON serialization *) 106 raise (Jmap_error.Parse_error "Response.to_json not yet implemented")