email/backend/
feature.rs

1//! # Backend feature
2//!
3//! A [`BackendFeature`] is an action like adding folder, listing
4//! envelopes or sending message. A feature needs a backend context to
5//! be executed.
6
7use std::sync::Arc;
8
9use async_trait::async_trait;
10
11use super::{context::BackendContext, AnyResult};
12
13/// Backend builder feature for checking up configuration and context
14/// integrity.
15///
16/// This feature is used to check the integrity of the context.
17#[async_trait]
18pub trait CheckUp: Send + Sync {
19    /// Define how the no operation should be executed.
20    async fn check_up(&self) -> AnyResult<()> {
21        Ok(())
22    }
23}
24
25/// The backend feature.
26///
27/// A backend feature is a function that takes a reference to a
28/// backend context as parameter and returns a feature.
29pub type BackendFeature<C, F> = Arc<dyn Fn(&C) -> Option<Box<F>> + Send + Sync>;
30
31/// The backend feature source.
32///
33/// This enum is used by the backend builder to determine where a
34/// specific backend feature should be taken from.
35#[derive(Default)]
36pub enum BackendFeatureSource<C: BackendContext, F: ?Sized> {
37    /// The feature should be disabled.
38    None,
39
40    /// The feature should be taken from the
41    /// [`super::BackendContextBuilder`].
42    #[default]
43    Context,
44
45    /// The feature should be taken from the
46    /// [`super::BackendBuilder`], using the given feature.
47    Backend(BackendFeature<C, F>),
48}
49
50impl<C, F> Clone for BackendFeatureSource<C, F>
51where
52    C: BackendContext,
53    F: ?Sized,
54{
55    fn clone(&self) -> Self {
56        match self {
57            Self::None => Self::None,
58            Self::Context => Self::Context,
59            Self::Backend(f) => Self::Backend(f.clone()),
60        }
61    }
62}
63
64impl<C, F, T> From<T> for BackendFeatureSource<C, F>
65where
66    C: BackendContext,
67    F: ?Sized,
68    T: Fn(&C) -> Option<Box<F>> + Send + Sync + 'static,
69{
70    fn from(value: T) -> Self {
71        Self::Backend(Arc::new(value))
72    }
73}