use serde::{Deserialize, Serialize};
use serde_json::Value;
use crate::error::JmapMethodError;
use crate::methods::{
handle_email_get, handle_email_query, handle_email_set, handle_email_submission_set,
handle_mailbox_get, handle_mailbox_query, handle_thread_get,
};
use crate::refs::resolve_references;
use crate::store::MailStore;
pub const JMAP_CORE_CAP: &str = "urn:ietf:params:jmap:core";
pub const JMAP_MAIL_CAP: &str = "urn:ietf:params:jmap:mail";
pub const JMAP_SUBMISSION_CAP: &str = "urn:ietf:params:jmap:submission";
#[derive(Debug, Clone, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct JmapRequest {
#[serde(default)]
pub using: Vec<String>,
pub method_calls: Vec<(String, Value, String)>,
}
#[derive(Debug, Clone, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct JmapResponse {
pub method_responses: Vec<(String, Value, String)>,
pub session_state: String,
}
pub async fn dispatch_method(
method: &str,
args: &Value,
user: &str,
store: &dyn MailStore,
) -> Result<(String, Value), JmapMethodError> {
match method {
"Mailbox/get" => handle_mailbox_get(args, user, store).await,
"Mailbox/query" => handle_mailbox_query(args, user, store).await,
"Email/get" => handle_email_get(args, user, store).await,
"Email/query" => handle_email_query(args, user, store).await,
"Email/set" => handle_email_set(args, user, store).await,
"Thread/get" => handle_thread_get(args, user, store).await,
"EmailSubmission/set" => handle_email_submission_set(args, user, store).await,
other => Err(JmapMethodError::UnknownMethod(other.to_string())),
}
}
pub async fn dispatch_request(
request: JmapRequest,
user: &str,
store: &dyn MailStore,
) -> JmapResponse {
let mut responses: Vec<(String, Value, String)> = Vec::new();
for (method, mut args, call_id) in request.method_calls {
resolve_references(&mut args, &responses);
match dispatch_method(&method, &args, user, store).await {
Ok((name, value)) => responses.push((name, value, call_id)),
Err(err) => responses.push(("error".to_string(), err.to_json(), call_id)),
}
}
JmapResponse {
method_responses: responses,
session_state: "0".to_string(),
}
}