My agentic slop goes here. Not intended for anyone else!
1(** Implementation of JMAP SearchSnippet objects (RFC 8621 Section 5) *) 2 3type t = { 4 email_id : Jmap.Id.t; 5 subject : string option; 6 preview : string option; 7} 8 9(** {1 SearchSnippet Construction} *) 10 11let create ~email_id ?subject ?preview () = { 12 email_id; 13 subject; 14 preview; 15} 16 17(** {1 Field Access} *) 18 19let email_id t = t.email_id 20let subject t = t.subject 21let preview t = t.preview 22 23(** {1 JSON Serialization} *) 24 25let to_json t = 26 let json_fields = [ 27 ("emailId", `String (Jmap.Id.to_string t.email_id)); 28 ] in 29 let json_fields = match t.subject with 30 | Some s -> ("subject", `String s) :: json_fields 31 | None -> ("subject", `Null) :: json_fields 32 in 33 let json_fields = match t.preview with 34 | Some p -> ("preview", `String p) :: json_fields 35 | None -> ("preview", `Null) :: json_fields 36 in 37 `Assoc (List.rev json_fields) 38 39let of_json json = 40 try 41 let open Yojson.Safe.Util in 42 let email_id_str = json |> member "emailId" |> to_string in 43 let email_id = match Jmap.Id.of_string email_id_str with 44 | Ok id -> id 45 | Error _ -> failwith ("Invalid emailId: " ^ email_id_str) 46 in 47 let subject = json |> member "subject" |> to_string_option in 48 let preview = json |> member "preview" |> to_string_option in 49 Ok (create ~email_id ?subject ?preview ()) 50 with 51 | exn -> Error ("Failed to parse SearchSnippet: " ^ Printexc.to_string exn) 52 53 54 55(** {1 SearchSnippet/get Method Support} *) 56 57module Get_args = struct 58 type t = { 59 account_id : string; 60 filter : Yojson.Safe.t; (* Use raw JSON for now since Filter module doesn't have of_json *) 61 email_ids : Jmap.Id.t list; 62 } 63 64 let create ~account_id ~filter ~email_ids () = { 65 account_id; 66 filter; 67 email_ids; 68 } 69 70 let account_id t = t.account_id 71 let filter t = t.filter 72 let email_ids t = t.email_ids 73 74 let to_json t = 75 `Assoc [ 76 ("accountId", `String t.account_id); 77 ("filter", t.filter); 78 ("emailIds", `List (List.map (fun id -> `String (Jmap.Id.to_string id)) t.email_ids)); 79 ] 80 81 let of_json json = 82 try 83 let open Yojson.Safe.Util in 84 let account_id = json |> member "accountId" |> to_string in 85 let filter = json |> member "filter" in 86 let email_ids_json = json |> member "emailIds" |> to_list in 87 let email_ids = List.map (fun id_json -> 88 let id_str = to_string id_json in 89 match Jmap.Id.of_string id_str with 90 | Ok id -> id 91 | Error _ -> failwith ("Invalid email ID: " ^ id_str) 92 ) email_ids_json in 93 Ok (create ~account_id ~filter ~email_ids ()) 94 with 95 | exn -> Error ("Failed to parse SearchSnippet/get args: " ^ Printexc.to_string exn) 96 97 98 end 99 100module Get_response = struct 101 type snippet = t (* Reference to the outer SearchSnippet.t *) 102 103 type response = { 104 account_id : string; 105 list : snippet list; 106 not_found : Jmap.Id.t list; 107 } 108 109 let create ~account_id ~list ?(not_found=[]) () = { 110 account_id; 111 list; 112 not_found; 113 } 114 115 let account_id t = t.account_id 116 let list t = t.list 117 let not_found t = t.not_found 118 119 let to_json t = 120 `Assoc [ 121 ("accountId", `String t.account_id); 122 ("list", `List (List.map to_json t.list)); 123 ("notFound", match t.not_found with 124 | [] -> `Null 125 | ids -> `List (List.map (fun id -> `String (Jmap.Id.to_string id)) ids)); 126 ] 127 128 let of_json json = 129 try 130 let open Yojson.Safe.Util in 131 let account_id = json |> member "accountId" |> to_string in 132 let list_json = json |> member "list" |> to_list in 133 let list = List.map (fun snippet_json -> 134 match of_json snippet_json with 135 | Ok snippet -> snippet 136 | Error err -> failwith err 137 ) list_json in 138 let not_found = match json |> member "notFound" with 139 | `Null -> [] 140 | `List ids -> List.map (fun id_json -> 141 let id_str = to_string id_json in 142 match Jmap.Id.of_string id_str with 143 | Ok id -> id 144 | Error _ -> failwith ("Invalid not found ID: " ^ id_str) 145 ) ids 146 | _ -> failwith "notFound must be null or array" 147 in 148 Ok (create ~account_id ~list ~not_found ()) 149 with 150 | exn -> Error ("Failed to parse SearchSnippet/get response: " ^ Printexc.to_string exn) 151 152 153 end