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