···
let mailbox_of_json json =
910
+
Printf.printf "Parsing mailbox JSON\n";
let id = get_string (find json ["id"]) in
913
+
Printf.printf "Got id: %s\n" id;
let name = get_string (find json ["name"]) in
912
-
let parent_id = find_opt json ["parentId"] |> Option.map get_string in
913
-
let role = find_opt json ["role"] |> Option.map (fun r -> Json.mailbox_role_of_string (get_string r)) in
916
+
Printf.printf "Got name: %s\n" name;
918
+
(* Handle parentId which can be null *)
920
+
match find_opt json ["parentId"] with
921
+
| Some (`Null) -> None
922
+
| Some (`String s) -> Some s
926
+
Printf.printf "Got parent_id: %s\n" (match parent_id with Some p -> p | None -> "None");
928
+
(* Handle role which might be null *)
930
+
match find_opt json ["role"] with
931
+
| Some (`Null) -> None
932
+
| Some (`String s) -> Some (Json.mailbox_role_of_string s)
936
+
Printf.printf "Got role\n";
let sort_order = get_int (find json ["sortOrder"]) in
939
+
Printf.printf "Got sort_order: %d\n" sort_order;
let total_emails = get_int (find json ["totalEmails"]) in
942
+
Printf.printf "Got total_emails: %d\n" total_emails;
let unread_emails = get_int (find json ["unreadEmails"]) in
945
+
Printf.printf "Got unread_emails: %d\n" unread_emails;
let total_threads = get_int (find json ["totalThreads"]) in
948
+
Printf.printf "Got total_threads: %d\n" total_threads;
let unread_threads = get_int (find json ["unreadThreads"]) in
951
+
Printf.printf "Got unread_threads: %d\n" unread_threads;
let is_subscribed = get_bool (find json ["isSubscribed"]) in
954
+
Printf.printf "Got is_subscribed: %b\n" is_subscribed;
let rights_json = find json ["myRights"] in
957
+
Printf.printf "Got rights_json\n";
Types.may_read_items = get_bool (find rights_json ["mayReadItems"]);
may_add_items = get_bool (find rights_json ["mayAddItems"]);
···
may_delete = get_bool (find rights_json ["mayDelete"]);
may_submit = get_bool (find rights_json ["maySubmit"]);
970
+
Printf.printf "Constructed my_rights\n";
···
985
+
Printf.printf "Constructed mailbox result\n";
948
-
| Not_found -> Error (Parse_error "Required field not found in mailbox object")
949
-
| Invalid_argument msg -> Error (Parse_error msg)
950
-
| e -> Error (Parse_error (Printexc.to_string e))
989
+
| Not_found as e ->
990
+
Printf.printf "Not_found error: %s\n" (Printexc.to_string e);
991
+
Printexc.print_backtrace stdout;
992
+
Error (Parse_error "Required field not found in mailbox object")
993
+
| Invalid_argument msg ->
994
+
Printf.printf "Invalid_argument error: %s\n" msg;
995
+
Error (Parse_error msg)
997
+
Printf.printf "Unknown error: %s\n" (Printexc.to_string e);
998
+
Error (Parse_error (Printexc.to_string e))
(** Convert JSON email object to OCaml type *)
1004
+
Printf.printf "Parsing email JSON\n";
let id = get_string (find json ["id"]) in
1007
+
Printf.printf "Got email id: %s\n" id;
let blob_id = get_string (find json ["blobId"]) in
let thread_id = get_string (find json ["threadId"]) in
···
let size = get_int (find json ["size"]) in
let received_at = get_string (find json ["receivedAt"]) in
977
-
let message_id = match find json ["messageId"] with
978
-
| `A ids -> List.map (fun id -> get_string id) ids
979
-
| _ -> raise (Invalid_argument "messageId is not an array")
1030
+
(* Handle messageId which might be an array or missing *)
1032
+
match find_opt json ["messageId"] with
1033
+
| Some (`A ids) -> List.map (fun id ->
1036
+
| _ -> raise (Invalid_argument "messageId item is not a string")
1038
+
| Some (`String s) -> [s] (* Handle single string case *)
1039
+
| None -> [] (* Handle missing case *)
1040
+
| _ -> raise (Invalid_argument "messageId has unexpected type")
(* Parse optional fields *)
···
Some (List.map (fun addr_json ->
987
-
let name = find_opt addr_json ["name"] |> Option.map get_string in
1049
+
match find_opt addr_json ["name"] with
1050
+
| Some (`String s) -> Some s
1051
+
| Some (`Null) -> None
let email = get_string (find addr_json ["email"]) in
989
-
let parameters = match find_opt addr_json ["parameters"] with
990
-
| Some (`O items) -> List.map (fun (k, v) -> (k, get_string v)) items
1057
+
match find_opt addr_json ["parameters"] with
1058
+
| Some (`O items) -> List.map (fun (k, v) ->
1060
+
| `String s -> (k, s)
{ Types.name; email; parameters }
···
998
-
let in_reply_to = find_opt json ["inReplyTo"] |> Option.map (function
999
-
| `A ids -> List.map get_string ids
1070
+
(* Handle optional string arrays with null handling *)
1071
+
let parse_string_array_opt field_name =
1072
+
match find_opt json [field_name] with
1073
+
| Some (`A ids) ->
1074
+
Some (List.filter_map (function
1075
+
| `String s -> Some s
1078
+
| Some (`Null) -> None
1003
-
let references = find_opt json ["references"] |> Option.map (function
1004
-
| `A ids -> List.map get_string ids
1083
+
let in_reply_to = parse_string_array_opt "inReplyTo" in
1084
+
let references = parse_string_array_opt "references" in
let sender = parse_email_addresses (find_opt json ["sender"]) in
let from = parse_email_addresses (find_opt json ["from"]) in
···
let bcc = parse_email_addresses (find_opt json ["bcc"]) in
let reply_to = parse_email_addresses (find_opt json ["replyTo"]) in
1015
-
let subject = find_opt json ["subject"] |> Option.map get_string in
1016
-
let sent_at = find_opt json ["sentAt"] |> Option.map get_string in
1017
-
let has_attachment = find_opt json ["hasAttachment"] |> Option.map get_bool in
1018
-
let preview = find_opt json ["preview"] |> Option.map get_string in
1093
+
(* Handle optional string fields with null handling *)
1094
+
let parse_string_opt field_name =
1095
+
match find_opt json [field_name] with
1096
+
| Some (`String s) -> Some s
1097
+
| Some (`Null) -> None
1102
+
let subject = parse_string_opt "subject" in
1103
+
let sent_at = parse_string_opt "sentAt" in
1105
+
(* Handle optional boolean fields with null handling *)
1106
+
let parse_bool_opt field_name =
1107
+
match find_opt json [field_name] with
1108
+
| Some (`Bool b) -> Some b
1109
+
| Some (`Null) -> None
1114
+
let has_attachment = parse_bool_opt "hasAttachment" in
1115
+
let preview = parse_string_opt "preview" in
(* Body parts parsing would go here - omitting for brevity *)
1118
+
Printf.printf "Email parsed successfully\n";
···
1050
-
| Not_found -> Error (Parse_error "Required field not found in email object")
1051
-
| Invalid_argument msg -> Error (Parse_error msg)
1052
-
| e -> Error (Parse_error (Printexc.to_string e))
1148
+
| Not_found as e ->
1149
+
Printf.printf "Email parse error - Not_found: %s\n" (Printexc.to_string e);
1150
+
Printexc.print_backtrace stdout;
1151
+
Error (Parse_error "Required field not found in email object")
1152
+
| Invalid_argument msg ->
1153
+
Printf.printf "Email parse error - Invalid_argument: %s\n" msg;
1154
+
Error (Parse_error msg)
1156
+
Printf.printf "Email parse error - Unknown: %s\n" (Printexc.to_string e);
1157
+
Error (Parse_error (Printexc.to_string e))
(** Login to a JMAP server and establish a connection
@param uri The URI of the JMAP server