1use serde::{Deserialize, Serialize};
8use serde_json::Value;
9
10use crate::error::JmapMethodError;
11use crate::methods::{
12 handle_email_get, handle_email_query, handle_email_set, handle_email_submission_set,
13 handle_mailbox_get, handle_mailbox_query, handle_thread_get,
14};
15use crate::refs::resolve_references;
16use crate::store::MailStore;
17
18pub const JMAP_CORE_CAP: &str = "urn:ietf:params:jmap:core";
20pub const JMAP_MAIL_CAP: &str = "urn:ietf:params:jmap:mail";
22pub const JMAP_SUBMISSION_CAP: &str = "urn:ietf:params:jmap:submission";
24
25#[derive(Debug, Clone, Deserialize)]
30#[serde(rename_all = "camelCase")]
31pub struct JmapRequest {
32 #[serde(default)]
36 pub using: Vec<String>,
37 pub method_calls: Vec<(String, Value, String)>,
41}
42
43#[derive(Debug, Clone, Serialize)]
45#[serde(rename_all = "camelCase")]
46pub struct JmapResponse {
47 pub method_responses: Vec<(String, Value, String)>,
50 pub session_state: String,
54}
55
56pub async fn dispatch_method(
63 method: &str,
64 args: &Value,
65 user: &str,
66 store: &dyn MailStore,
67) -> Result<(String, Value), JmapMethodError> {
68 match method {
69 "Mailbox/get" => handle_mailbox_get(args, user, store).await,
70 "Mailbox/query" => handle_mailbox_query(args, user, store).await,
71 "Email/get" => handle_email_get(args, user, store).await,
72 "Email/query" => handle_email_query(args, user, store).await,
73 "Email/set" => handle_email_set(args, user, store).await,
74 "Thread/get" => handle_thread_get(args, user, store).await,
75 "EmailSubmission/set" => handle_email_submission_set(args, user, store).await,
76 other => Err(JmapMethodError::UnknownMethod(other.to_string())),
77 }
78}
79
80pub async fn dispatch_request(
84 request: JmapRequest,
85 user: &str,
86 store: &dyn MailStore,
87) -> JmapResponse {
88 let mut responses: Vec<(String, Value, String)> = Vec::new();
89
90 for (method, mut args, call_id) in request.method_calls {
91 resolve_references(&mut args, &responses);
92
93 match dispatch_method(&method, &args, user, store).await {
94 Ok((name, value)) => responses.push((name, value, call_id)),
95 Err(err) => responses.push(("error".to_string(), err.to_json(), call_id)),
96 }
97 }
98
99 JmapResponse {
100 method_responses: responses,
101 session_state: "0".to_string(),
102 }
103}