samotop_core/mail/
builder.rs

1use crate::{mail::*, smtp::*};
2use std::ops::{Add, AddAssign};
3
4/// Builds MailService from components with a builder pattern.
5///
6/// Add components with a + sign. The component must implement `MailSetup<T>`
7/// and may depend with T on traits the `Configuration` struct implements.
8/// Finally call `build()` or `build_with_driver()`
9#[derive(Default, Debug)]
10pub struct Builder;
11
12/// Composing a mail service with +
13impl<T: MailSetup<Configuration>> Add<T> for Builder {
14    type Output = BuilderWithConfig;
15    /// Add given mail setup to the service configuration
16    fn add(self, setup: T) -> Self::Output {
17        BuilderWithConfig::default() + setup
18    }
19}
20
21impl Builder {
22    /// Start with empty configuration
23    pub fn empty() -> BuilderWithConfig {
24        BuilderWithConfig::default()
25    }
26    /// Use a given MailSetup to build a MailService.
27    ///
28    /// See MailSetup for examples. Prefer to build with the + sign.
29    pub fn using(self, setup: impl MailSetup<Configuration>) -> BuilderWithConfig {
30        BuilderWithConfig::default() + setup
31    }
32    #[cfg(feature = "driver")]
33    /// Finalize and produce the MailService.
34    pub fn build(self) -> Service {
35        BuilderWithConfig::default().build()
36    }
37}
38
39/// Represents the on-going builder configuration
40#[derive(Default)]
41pub struct BuilderWithConfig {
42    config: Configuration,
43}
44
45/// Composing a mail service with +
46impl<T: MailSetup<Configuration>> Add<T> for BuilderWithConfig {
47    type Output = Self;
48    /// Add given mail setup to the service configuration
49    fn add(mut self, setup: T) -> Self::Output {
50        self += setup;
51        self
52    }
53}
54/// Composing a mail service with +=
55impl<T: MailSetup<Configuration>> AddAssign<T> for BuilderWithConfig {
56    fn add_assign(&mut self, setup: T) {
57        trace!(
58            "Service builder {} using setup {:?}",
59            self.config.id(),
60            setup
61        );
62        setup.setup(&mut self.config)
63    }
64}
65
66impl BuilderWithConfig {
67    /// Use a given MailSetup to build a MailService.
68    ///
69    /// See MailSetup for examples. Prefer to build with the + sign.
70    pub fn using(self, setup: impl MailSetup<Configuration>) -> Self {
71        self + setup
72    }
73
74    #[cfg(feature = "driver")]
75    /// Finalize and produce the MailService.
76    pub fn build(self) -> Service {
77        self.build_with_driver(crate::smtp::SmtpDriver)
78    }
79
80    /// Finalize and produce the MailService.
81    pub fn build_with_driver(self, driver: impl Drive + Send + Sync + 'static) -> Service {
82        self.config.into_service(driver)
83    }
84}