Trait email::backend::mapper::SomeBackendContextBuilderMapper
source · pub trait SomeBackendContextBuilderMapper<CB>where
Self: BackendContextBuilder,
Self::Context: AsRef<Option<CB::Context>> + 'static,
CB: BackendContextBuilder,
CB::Context: BackendContext + 'static,{
Show 20 methods
// Provided methods
fn map_feature<T: ?Sized + 'static>(
&self,
f: Option<BackendFeature<CB::Context, T>>
) -> Option<BackendFeature<Self::Context, T>> { ... }
fn check_up_with_some(
&self,
cb: &Option<CB>
) -> Option<BackendFeature<Self::Context, dyn CheckUp>> { ... }
fn add_folder_with_some(
&self,
cb: &Option<CB>
) -> Option<BackendFeature<Self::Context, dyn AddFolder>> { ... }
fn list_folders_with_some(
&self,
cb: &Option<CB>
) -> Option<BackendFeature<Self::Context, dyn ListFolders>> { ... }
fn expunge_folder_with_some(
&self,
cb: &Option<CB>
) -> Option<BackendFeature<Self::Context, dyn ExpungeFolder>> { ... }
fn purge_folder_with_some(
&self,
cb: &Option<CB>
) -> Option<BackendFeature<Self::Context, dyn PurgeFolder>> { ... }
fn delete_folder_with_some(
&self,
cb: &Option<CB>
) -> Option<BackendFeature<Self::Context, dyn DeleteFolder>> { ... }
fn get_envelope_with_some(
&self,
cb: &Option<CB>
) -> Option<BackendFeature<Self::Context, dyn GetEnvelope>> { ... }
fn list_envelopes_with_some(
&self,
cb: &Option<CB>
) -> Option<BackendFeature<Self::Context, dyn ListEnvelopes>> { ... }
fn watch_envelopes_with_some(
&self,
cb: &Option<CB>
) -> Option<BackendFeature<Self::Context, dyn WatchEnvelopes>> { ... }
fn add_flags_with_some(
&self,
cb: &Option<CB>
) -> Option<BackendFeature<Self::Context, dyn AddFlags>> { ... }
fn set_flags_with_some(
&self,
cb: &Option<CB>
) -> Option<BackendFeature<Self::Context, dyn SetFlags>> { ... }
fn remove_flags_with_some(
&self,
cb: &Option<CB>
) -> Option<BackendFeature<Self::Context, dyn RemoveFlags>> { ... }
fn add_message_with_some(
&self,
cb: &Option<CB>
) -> Option<BackendFeature<Self::Context, dyn AddMessage>> { ... }
fn send_message_with_some(
&self,
cb: &Option<CB>
) -> Option<BackendFeature<Self::Context, dyn SendMessage>> { ... }
fn peek_messages_with_some(
&self,
cb: &Option<CB>
) -> Option<BackendFeature<Self::Context, dyn PeekMessages>> { ... }
fn get_messages_with_some(
&self,
cb: &Option<CB>
) -> Option<BackendFeature<Self::Context, dyn GetMessages>> { ... }
fn copy_messages_with_some(
&self,
cb: &Option<CB>
) -> Option<BackendFeature<Self::Context, dyn CopyMessages>> { ... }
fn move_messages_with_some(
&self,
cb: &Option<CB>
) -> Option<BackendFeature<Self::Context, dyn MoveMessages>> { ... }
fn delete_messages_with_some(
&self,
cb: &Option<CB>
) -> Option<BackendFeature<Self::Context, dyn DeleteMessages>> { ... }
}
Expand description
Map a backend feature from subcontext B to context A.
This is useful when you have a context composed of multiple subcontexts. It prevents you to manually map the feature.
See a usage example at ../../tests/dynamic_backend.rs
.
ⓘ
use async_trait::async_trait;
use email::{
account::config::{passwd::PasswdConfig, AccountConfig},
backend::{
context::BackendContextBuilder, feature::BackendFeature, macros::BackendContext,
mapper::SomeBackendContextBuilderMapper, Backend, BackendBuilder,
},
folder::{list::ListFolders, Folder, FolderKind},
imap::{
config::{ImapAuthConfig, ImapConfig, ImapEncryptionKind},
ImapContextBuilder, ImapContextSync,
},
smtp::{SmtpContextBuilder, SmtpContextSync},
AnyResult,
};
use email_testing_server::with_email_testing_server;
use secret::Secret;
use std::sync::Arc;
#[tokio::test(flavor = "multi_thread")]
async fn test_dynamic_backend() {
env_logger::builder().is_test(true).init();
with_email_testing_server(|ports| async move {
let account_config = Arc::new(AccountConfig::default());
let imap_config = Arc::new(ImapConfig {
host: "localhost".into(),
port: ports.imap,
encryption: Some(ImapEncryptionKind::None),
login: "bob".into(),
auth: ImapAuthConfig::Passwd(PasswdConfig(Secret::new_raw("password"))),
..Default::default()
});
// 1. define custom context
#[derive(BackendContext)]
struct DynamicContext {
imap: Option<ImapContextSync>,
smtp: Option<SmtpContextSync>,
}
// 2. implement AsRef for mapping features
impl AsRef<Option<ImapContextSync>> for DynamicContext {
fn as_ref(&self) -> &Option<ImapContextSync> {
&self.imap
}
}
impl AsRef<Option<SmtpContextSync>> for DynamicContext {
fn as_ref(&self) -> &Option<SmtpContextSync> {
&self.smtp
}
}
// 3. define custom context builder
#[derive(Clone)]
struct DynamicContextBuilder {
imap: Option<ImapContextBuilder>,
smtp: Option<SmtpContextBuilder>,
}
// 4. implement backend context builder
#[async_trait]
impl BackendContextBuilder for DynamicContextBuilder {
type Context = DynamicContext;
// override the list folders feature using the imap builder
fn list_folders(&self) -> Option<BackendFeature<Self::Context, dyn ListFolders>> {
self.list_folders_with_some(&self.imap)
}
async fn build(self) -> AnyResult<Self::Context> {
let imap = match self.imap {
Some(imap) => Some(imap.build().await?),
None => None,
};
let smtp = match self.smtp {
Some(smtp) => Some(smtp.build().await?),
None => None,
};
Ok(DynamicContext { imap, smtp })
}
}
// 5. plug all together
let ctx_builder = DynamicContextBuilder {
imap: Some(ImapContextBuilder::new(
account_config.clone(),
imap_config.clone(),
)),
smtp: None,
};
let backend_builder = BackendBuilder::new(account_config.clone(), ctx_builder);
let backend: Backend<DynamicContext> = backend_builder.build().await.unwrap();
let folders = backend.list_folders().await.unwrap();
assert!(folders.contains(&Folder {
kind: Some(FolderKind::Inbox),
name: "INBOX".into(),
desc: "".into()
}));
})
.await
}
Provided Methods§
fn map_feature<T: ?Sized + 'static>( &self, f: Option<BackendFeature<CB::Context, T>> ) -> Option<BackendFeature<Self::Context, T>>
fn check_up_with_some( &self, cb: &Option<CB> ) -> Option<BackendFeature<Self::Context, dyn CheckUp>>
fn add_folder_with_some( &self, cb: &Option<CB> ) -> Option<BackendFeature<Self::Context, dyn AddFolder>>
fn list_folders_with_some( &self, cb: &Option<CB> ) -> Option<BackendFeature<Self::Context, dyn ListFolders>>
fn expunge_folder_with_some( &self, cb: &Option<CB> ) -> Option<BackendFeature<Self::Context, dyn ExpungeFolder>>
fn purge_folder_with_some( &self, cb: &Option<CB> ) -> Option<BackendFeature<Self::Context, dyn PurgeFolder>>
fn delete_folder_with_some( &self, cb: &Option<CB> ) -> Option<BackendFeature<Self::Context, dyn DeleteFolder>>
fn get_envelope_with_some( &self, cb: &Option<CB> ) -> Option<BackendFeature<Self::Context, dyn GetEnvelope>>
fn list_envelopes_with_some( &self, cb: &Option<CB> ) -> Option<BackendFeature<Self::Context, dyn ListEnvelopes>>
fn watch_envelopes_with_some( &self, cb: &Option<CB> ) -> Option<BackendFeature<Self::Context, dyn WatchEnvelopes>>
fn add_flags_with_some( &self, cb: &Option<CB> ) -> Option<BackendFeature<Self::Context, dyn AddFlags>>
fn set_flags_with_some( &self, cb: &Option<CB> ) -> Option<BackendFeature<Self::Context, dyn SetFlags>>
fn remove_flags_with_some( &self, cb: &Option<CB> ) -> Option<BackendFeature<Self::Context, dyn RemoveFlags>>
fn add_message_with_some( &self, cb: &Option<CB> ) -> Option<BackendFeature<Self::Context, dyn AddMessage>>
fn send_message_with_some( &self, cb: &Option<CB> ) -> Option<BackendFeature<Self::Context, dyn SendMessage>>
fn peek_messages_with_some( &self, cb: &Option<CB> ) -> Option<BackendFeature<Self::Context, dyn PeekMessages>>
fn get_messages_with_some( &self, cb: &Option<CB> ) -> Option<BackendFeature<Self::Context, dyn GetMessages>>
fn copy_messages_with_some( &self, cb: &Option<CB> ) -> Option<BackendFeature<Self::Context, dyn CopyMessages>>
fn move_messages_with_some( &self, cb: &Option<CB> ) -> Option<BackendFeature<Self::Context, dyn MoveMessages>>
fn delete_messages_with_some( &self, cb: &Option<CB> ) -> Option<BackendFeature<Self::Context, dyn DeleteMessages>>
Object Safety§
This trait is not object safe.
Implementors§
impl<CB1, CB2> SomeBackendContextBuilderMapper<CB2> for CB1where
CB1: BackendContextBuilder,
CB1::Context: AsRef<Option<CB2::Context>> + 'static,
CB2: BackendContextBuilder,
CB2::Context: BackendContext + 'static,
Automatically implement SomeBackendContextBuilderMapper
.