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}