lettre/transport/stub/
mod.rs1use std::{
44 error::Error as StdError,
45 fmt,
46 sync::{Arc, Mutex},
47};
48
49#[cfg(any(feature = "tokio1", feature = "async-std1"))]
50use async_trait::async_trait;
51
52#[cfg(any(feature = "tokio1", feature = "async-std1"))]
53use crate::AsyncTransport;
54use crate::{address::Envelope, Transport};
55
56#[non_exhaustive]
58#[derive(Debug, Copy, Clone)]
59pub struct Error;
60
61impl fmt::Display for Error {
62 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
63 f.write_str("stub error")
64 }
65}
66
67impl StdError for Error {}
68
69#[derive(Debug, Clone)]
71pub struct StubTransport {
72 response: Result<(), Error>,
73 message_log: Arc<Mutex<Vec<(Envelope, String)>>>,
74}
75
76#[derive(Debug, Clone)]
78#[cfg(any(feature = "tokio1", feature = "async-std1"))]
79#[cfg_attr(docsrs, doc(cfg(any(feature = "tokio1", feature = "async-std1"))))]
80pub struct AsyncStubTransport {
81 response: Result<(), Error>,
82 message_log: Arc<Mutex<Vec<(Envelope, String)>>>,
83}
84
85impl StubTransport {
86 pub fn new(response: Result<(), Error>) -> Self {
88 Self {
89 response,
90 message_log: Arc::new(Mutex::new(vec![])),
91 }
92 }
93
94 pub fn new_ok() -> Self {
96 Self {
97 response: Ok(()),
98 message_log: Arc::new(Mutex::new(vec![])),
99 }
100 }
101
102 pub fn new_error() -> Self {
104 Self {
105 response: Err(Error),
106 message_log: Arc::new(Mutex::new(vec![])),
107 }
108 }
109
110 pub fn messages(&self) -> Vec<(Envelope, String)> {
112 self.message_log
113 .lock()
114 .expect("Couldn't acquire lock to write message log")
115 .clone()
116 }
117}
118
119#[cfg(any(feature = "async-std1", feature = "tokio1"))]
120impl AsyncStubTransport {
121 pub fn new(response: Result<(), Error>) -> Self {
123 Self {
124 response,
125 message_log: Arc::new(Mutex::new(vec![])),
126 }
127 }
128
129 pub fn new_ok() -> Self {
131 Self {
132 response: Ok(()),
133 message_log: Arc::new(Mutex::new(vec![])),
134 }
135 }
136
137 pub fn new_error() -> Self {
139 Self {
140 response: Err(Error),
141 message_log: Arc::new(Mutex::new(vec![])),
142 }
143 }
144
145 #[cfg(any(feature = "tokio1", feature = "async-std1"))]
147 pub async fn messages(&self) -> Vec<(Envelope, String)> {
148 self.message_log.lock().unwrap().clone()
149 }
150}
151
152impl Transport for StubTransport {
153 type Ok = ();
154 type Error = Error;
155
156 fn send_raw(&self, envelope: &Envelope, email: &[u8]) -> Result<Self::Ok, Self::Error> {
157 self.message_log
158 .lock()
159 .expect("Couldn't acquire lock to write message log")
160 .push((envelope.clone(), String::from_utf8_lossy(email).into()));
161 self.response
162 }
163}
164
165#[cfg(any(feature = "tokio1", feature = "async-std1"))]
166#[async_trait]
167impl AsyncTransport for AsyncStubTransport {
168 type Ok = ();
169 type Error = Error;
170
171 async fn send_raw(&self, envelope: &Envelope, email: &[u8]) -> Result<Self::Ok, Self::Error> {
172 self.message_log
173 .lock()
174 .unwrap()
175 .push((envelope.clone(), String::from_utf8_lossy(email).into()));
176 self.response
177 }
178}