use std::collections::HashMap;
use serde::{Deserialize, Serialize};
pub const JMAP_MAIL_URI: &str = "urn:ietf:params:jmap:mail";
pub const JMAP_SUBMISSION_URI: &str = "urn:ietf:params:jmap:submission";
pub const JMAP_VACATIONRESPONSE_URI: &str = "urn:ietf:params:jmap:vacationresponse";
#[non_exhaustive]
#[derive(Debug, Clone, PartialEq, Eq, Default, Serialize, Deserialize)]
pub struct MailCapability {}
#[non_exhaustive]
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct MailAccountCapability {
pub max_mailboxes_per_email: Option<u64>,
pub max_mailbox_depth: Option<u64>,
pub max_size_mailbox_name: u64,
pub max_size_attachments_per_email: u64,
pub email_query_sort_options: Vec<String>,
pub may_create_top_level_mailbox: bool,
}
#[non_exhaustive]
#[derive(Debug, Clone, PartialEq, Eq, Default, Serialize, Deserialize)]
pub struct SubmissionCapability {}
#[non_exhaustive]
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SubmissionAccountCapability {
pub max_delayed_send: u64,
pub submission_extensions: HashMap<String, Vec<String>>,
}
#[non_exhaustive]
#[derive(Debug, Clone, PartialEq, Eq, Default, Serialize, Deserialize)]
pub struct VacationResponseCapability {}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn mail_account_capability_round_trip() {
let json = r#"{"maxMailboxesPerEmail":null,"maxMailboxDepth":10,"maxSizeMailboxName":100,"maxSizeAttachmentsPerEmail":50000000,"emailQuerySortOptions":["receivedAt","size"],"mayCreateTopLevelMailbox":true}"#;
let cap: MailAccountCapability = serde_json::from_str(json).expect("must parse");
assert!(cap.max_mailboxes_per_email.is_none());
assert_eq!(cap.max_mailbox_depth, Some(10));
assert_eq!(cap.max_size_mailbox_name, 100);
assert_eq!(cap.max_size_attachments_per_email, 50_000_000);
assert_eq!(
cap.email_query_sort_options,
vec!["receivedAt".to_owned(), "size".to_owned()]
);
assert!(cap.may_create_top_level_mailbox);
let back = serde_json::to_string(&cap).expect("serialize");
assert_eq!(back, json);
}
#[test]
fn mail_capability_session_level_is_empty_object() {
let cap = MailCapability::default();
let json = serde_json::to_string(&cap).expect("serialize");
assert_eq!(json, "{}");
let back: MailCapability = serde_json::from_str("{}").expect("must parse");
assert_eq!(back, cap);
}
#[test]
fn submission_account_capability_round_trip() {
let json = r#"{"maxDelayedSend":86400,"submissionExtensions":{"FUTURERELEASE":["86400","2024-01-01T00:00:00Z"]}}"#;
let cap: SubmissionAccountCapability = serde_json::from_str(json).expect("must parse");
assert_eq!(cap.max_delayed_send, 86_400);
assert_eq!(
cap.submission_extensions.get("FUTURERELEASE"),
Some(&vec!["86400".to_owned(), "2024-01-01T00:00:00Z".to_owned()])
);
let back = serde_json::to_string(&cap).expect("serialize");
assert_eq!(back, json);
}
#[test]
fn submission_capability_session_level_is_empty_object() {
let cap = SubmissionCapability::default();
let json = serde_json::to_string(&cap).expect("serialize");
assert_eq!(json, "{}");
}
#[test]
fn vacation_response_capability_is_empty_object() {
let cap = VacationResponseCapability::default();
let json = serde_json::to_string(&cap).expect("serialize");
assert_eq!(json, "{}");
let back: VacationResponseCapability = serde_json::from_str("{}").expect("must parse");
assert_eq!(back, cap);
}
#[test]
fn capability_uri_constants_match_rfc8621() {
assert_eq!(JMAP_MAIL_URI, "urn:ietf:params:jmap:mail");
assert_eq!(JMAP_SUBMISSION_URI, "urn:ietf:params:jmap:submission");
assert_eq!(
JMAP_VACATIONRESPONSE_URI,
"urn:ietf:params:jmap:vacationresponse"
);
}
}