this repo has no description

Refactor fastmail_list to use higher-level API functions

Replace the manual construction of JMAP requests with proper higher-level
library calls from Jmap_mail. This improves code clarity and ensures that
the example demonstrates the recommended way to use the library.

🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>

Changed files
+45 -108
bin
+45 -108
bin/fastmail_list.ml
··· 64 64 in 65 65 is_unread_keyword || is_not_seen 66 66 67 - (** Example function demonstrating how to use result references for chained requests *) 67 + (** Example function demonstrating how to use higher-level library functions for JMAP requests *) 68 68 let demo_result_references conn account_id = 69 - let open Jmap.Types in 70 - 71 - (* Create a request that chains the following operations: 72 - 1. Get mailboxes 73 - 2. Query emails in the first mailbox found 74 - 3. Get the full email objects for those IDs 75 - *) 76 - 77 - (* Create method call IDs *) 78 - let mailbox_get_id = "mailboxGet" in 79 - let email_query_id = "emailQuery" in 80 - let email_get_id = "emailGet" in 81 - 82 - (* First call: Get mailboxes *) 83 - let mailbox_get_call = { 84 - name = "Mailbox/get"; 85 - arguments = `O [ 86 - ("accountId", `String account_id); 87 - ]; 88 - method_call_id = mailbox_get_id; 89 - } in 90 - 91 - (* Second call: Query emails in the first mailbox using result reference *) 92 - (* Create reference to the first mailbox ID from the previous result *) 93 - let mailbox_id_ref = Jmap.ResultReference.create 94 - ~result_of:mailbox_get_id 95 - ~name:"Mailbox/get" 96 - ~path:"/list/0/id" in 97 - 98 - (* Use the reference to create the query arguments *) 99 - let (mailbox_id_ref_key, mailbox_id_ref_value) = 100 - Jmap.ResultReference.reference_arg "inMailbox" mailbox_id_ref in 101 - 102 - let email_query_call = { 103 - name = "Email/query"; 104 - arguments = `O [ 105 - ("accountId", `String account_id); 106 - ("filter", `O [ 107 - (mailbox_id_ref_key, mailbox_id_ref_value) 108 - ]); 109 - ("limit", `Float 10.0); 110 - ]; 111 - method_call_id = email_query_id; 112 - } in 113 - 114 - (* Third call: Get full email objects using the query result *) 115 - (* Create reference to the email IDs from the query result *) 116 - let email_ids_ref = Jmap.ResultReference.create 117 - ~result_of:email_query_id 118 - ~name:"Email/query" 119 - ~path:"/ids" in 120 - 121 - (* Use the reference to create the get arguments *) 122 - let (email_ids_ref_key, email_ids_ref_value) = 123 - Jmap.ResultReference.reference_arg "ids" email_ids_ref in 124 - 125 - let email_get_call = { 126 - name = "Email/get"; 127 - arguments = `O [ 128 - ("accountId", `String account_id); 129 - (email_ids_ref_key, email_ids_ref_value) 130 - ]; 131 - method_call_id = email_get_id; 132 - } in 133 - 134 - (* Create the complete request with all three method calls *) 135 - let request = { 136 - using = [ 137 - Jmap.Capability.to_string Jmap.Capability.Core; 138 - Jmap_mail.Capability.to_string Jmap_mail.Capability.Mail 139 - ]; 140 - method_calls = [ 141 - mailbox_get_call; 142 - email_query_call; 143 - email_get_call 144 - ]; 145 - created_ids = None; 146 - } in 147 - 148 - (* Make the request *) 149 - let* response_result = Jmap.Api.make_request conn.config request in 150 69 Printf.printf "\nResult Reference Demo:\n"; 151 70 Printf.printf "=====================\n"; 152 71 153 - match response_result with 72 + (* Step 1: Get all mailboxes *) 73 + let* mailboxes_result = Jmap_mail.get_mailboxes conn ~account_id in 74 + match mailboxes_result with 154 75 | Error err -> 155 - Printf.printf "Error executing chained request: %s\n" 76 + Printf.printf "Error getting mailboxes: %s\n" 156 77 (match err with 157 78 | Jmap.Api.Connection_error msg -> "Connection error: " ^ msg 158 79 | Jmap.Api.HTTP_error (code, body) -> Printf.sprintf "HTTP error %d: %s" code body 159 80 | Jmap.Api.Parse_error msg -> "Parse error: " ^ msg 160 81 | Jmap.Api.Authentication_error -> "Authentication error"); 161 82 Lwt.return_unit 162 - | Ok response -> 163 - (* Process the response *) 164 - try 165 - (* Look for the Email/get method response *) 166 - let email_get_result = List.find (fun (inv : Ezjsonm.value invocation) -> 167 - inv.name = "Email/get" 168 - ) response.method_responses in 169 - 170 - (* Extract the email list from the response *) 171 - let list = Ezjsonm.find email_get_result.arguments ["list"] in 172 - match list with 173 - | `A emails -> 174 - Printf.printf "Successfully retrieved %d emails using chained result references!\n" 175 - (List.length emails); 176 - Lwt.return_unit 177 - | _ -> 178 - Printf.printf "Unexpected email list format in response.\n"; 179 - Lwt.return_unit 180 - with 181 - | Not_found -> 182 - Printf.printf "No Email/get result found in response.\n"; 183 - Lwt.return_unit 184 - | e -> 185 - Printf.printf "Error processing response: %s\n" (Printexc.to_string e); 83 + 84 + | Ok mailboxes -> 85 + (* Step 2: Get the first mailbox for this demonstration *) 86 + match mailboxes with 87 + | [] -> 88 + Printf.printf "No mailboxes found.\n"; 186 89 Lwt.return_unit 90 + 91 + | first_mailbox :: _ -> 92 + Printf.printf "Using mailbox: %s\n" first_mailbox.Mail.name; 93 + 94 + (* Step 3: Get emails from the selected mailbox *) 95 + let* emails_result = Jmap_mail.get_messages_in_mailbox 96 + conn 97 + ~account_id 98 + ~mailbox_id:first_mailbox.Mail.id 99 + ~limit:10 100 + () 101 + in 102 + 103 + match emails_result with 104 + | Error err -> 105 + Printf.printf "Error getting emails: %s\n" 106 + (match err with 107 + | Jmap.Api.Connection_error msg -> "Connection error: " ^ msg 108 + | Jmap.Api.HTTP_error (code, body) -> Printf.sprintf "HTTP error %d: %s" code body 109 + | Jmap.Api.Parse_error msg -> "Parse error: " ^ msg 110 + | Jmap.Api.Authentication_error -> "Authentication error"); 111 + Lwt.return_unit 112 + 113 + | Ok emails -> 114 + Printf.printf "Successfully retrieved %d emails using the high-level library API!\n" 115 + (List.length emails); 116 + 117 + (* Display some basic information about the emails *) 118 + List.iteri (fun i (email:Jmap_mail.Types.email) -> 119 + let subject = Option.value ~default:"<no subject>" email.Mail.subject in 120 + Printf.printf " %d. %s\n" (i + 1) subject 121 + ) emails; 122 + 123 + Lwt.return_unit 187 124 188 125 (** Main function *) 189 126 let main () =