/* * SPDX-FileCopyrightText: 2020 Stalwart Labs LLC * * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL */ pub mod capability; pub mod deserialize; pub mod method; pub mod parser; pub mod reference; pub mod websocket; use self::method::MethodName; use crate::{ method::{ availability::GetAvailabilityRequest, changes::ChangesRequest, copy::{CopyBlobRequest, CopyRequest}, get::GetRequest, import::ImportEmailRequest, lookup::BlobLookupRequest, parse::ParseRequest, query::QueryRequest, query_changes::QueryChangesRequest, search_snippet::GetSearchSnippetRequest, set::SetRequest, upload::BlobUploadRequest, validate::ValidateSieveScriptRequest, }, object::{ AnyId, addressbook::AddressBook, blob::Blob, calendar::Calendar, calendar_event::CalendarEvent, calendar_event_notification::CalendarEventNotification, contact::ContactCard, email::Email, email_submission::EmailSubmission, file_node::FileNode, identity::Identity, mailbox::Mailbox, participant_identity::ParticipantIdentity, principal::Principal, push_subscription::PushSubscription, quota::Quota, registry::Registry, share_notification::ShareNotification, sieve::Sieve, thread::Thread, vacation_response::VacationResponse, }, request::{capability::CapabilityIds, reference::MaybeIdReference}, }; use jmap_tools::{Null, Value}; use std::{collections::HashMap, fmt::Debug, str::FromStr}; use utils::map::vec_map::VecMap; #[derive(Debug)] pub struct Request<'x> { pub using: CapabilityIds, pub method_calls: Vec>>, pub created_ids: Option>, } #[derive(Debug)] pub struct Call { pub id: String, pub name: MethodName, pub method: T, } #[derive(Debug)] pub enum RequestMethod<'x> { Get(GetRequestMethod), Set(SetRequestMethod<'x>), Changes(Box), Copy(CopyRequestMethod<'x>), ImportEmail(Box), Parse(ParseRequestMethod), Query(QueryRequestMethod), QueryChanges(QueryChangesRequestMethod), SearchSnippet(Box), ValidateScript(Box), LookupBlob(Box), UploadBlob(Box), Echo(Value<'x, Null, Null>), Error(trc::Error), } #[derive(Debug)] pub enum GetRequestMethod { Email(Box>), Mailbox(Box>), Thread(Box>), Identity(Box>), EmailSubmission(Box>), PushSubscription(Box>), Sieve(Box>), VacationResponse(Box>), Principal(Box>), PrincipalAvailability(Box), Quota(Box>), Blob(Box>), AddressBook(Box>), ContactCard(Box>), FileNode(Box>), Calendar(Box>), CalendarEvent(Box>), CalendarEventNotification(Box>), ParticipantIdentity(Box>), ShareNotification(Box>), Registry(Box>), } #[derive(Debug)] pub enum SetRequestMethod<'x> { Email(Box>), Mailbox(Box>), Identity(Box>), EmailSubmission(Box>), PushSubscription(Box>), Sieve(Box>), VacationResponse(Box>), AddressBook(Box>), ContactCard(Box>), FileNode(Box>), ShareNotification(Box>), Calendar(Box>), CalendarEvent(Box>), CalendarEventNotification(Box>), ParticipantIdentity(Box>), Registry(Box>), } #[derive(Debug)] pub enum CopyRequestMethod<'x> { Email(Box>), ContactCard(Box>), CalendarEvent(Box>), Blob(Box), } #[derive(Debug)] pub enum QueryRequestMethod { Email(Box>), Mailbox(Box>), EmailSubmission(Box>), Sieve(Box>), Principal(Box>), Quota(Box>), AddressBook(Box>), ContactCard(Box>), FileNode(Box>), Calendar(Box>), CalendarEvent(Box>), CalendarEventNotification(Box>), ShareNotification(Box>), Registry(Box>), } #[derive(Debug)] pub enum QueryChangesRequestMethod { Email(Box>), Mailbox(Box>), EmailSubmission(Box>), Principal(Box>), Quota(Box>), ContactCard(Box>), FileNode(Box>), CalendarEvent(Box>), CalendarEventNotification(Box>), ShareNotification(Box>), } #[derive(Debug)] pub enum ParseRequestMethod { Email(Box>), ContactCard(Box>), CalendarEvent(Box>), } #[derive(Debug, Clone, PartialEq, Eq)] pub enum MaybeInvalid { Value(V), Invalid(String), } impl<'de, V: FromStr> serde::Deserialize<'de> for MaybeInvalid { fn deserialize(deserializer: D) -> Result where D: serde::Deserializer<'de>, { let value = <&str>::deserialize(deserializer)?; if let Ok(id) = V::from_str(value) { Ok(MaybeInvalid::Value(id)) } else { Ok(MaybeInvalid::Invalid(value.to_string())) } } } impl Default for MaybeInvalid { fn default() -> Self { MaybeInvalid::Invalid("".to_string()) } } #[allow(clippy::derivable_impls)] impl Default for Request<'_> { fn default() -> Self { Request { using: CapabilityIds::default(), method_calls: Vec::new(), created_ids: None, } } } impl MaybeInvalid where T: FromStr, { pub fn try_unwrap(self) -> Option { match self { MaybeInvalid::Value(id) => Some(id), MaybeInvalid::Invalid(_) => None, } } } pub trait IntoValid { type Item; fn into_valid(self) -> impl Iterator; } impl IntoValid for Vec> { type Item = T; fn into_valid(self) -> impl Iterator { self.into_iter().filter_map(|v| v.try_unwrap()) } } impl IntoValid for Vec> { type Item = T; fn into_valid(self) -> impl Iterator { self.into_iter().filter_map(|v| v.try_unwrap()) } } impl IntoValid for VecMap, V> { type Item = (T, V); fn into_valid(self) -> impl Iterator { self.into_iter() .filter_map(|(k, v)| k.try_unwrap().map(|k| (k, v))) } } impl IntoValid for VecMap, V> { type Item = (T, V); fn into_valid(self) -> impl Iterator { self.into_iter() .filter_map(|(k, v)| k.try_unwrap().map(|k| (k, v))) } }