mail_tm_rs/lib.rs
1//! Mail-TM API implementation using common HTTP crates
2//!
3//! Provides an implementation of the Mail-TM 2.0.0 API
4//! Largely it is around 80% complete and is missing possibly future deprecations such as sources.
5//! At present the dependencies are very strict and requires future testing to open it up.
6//!
7//! Expect some breaking changes until v1.0.0 but will try to document them as best I can.
8//!
9//! [`Mail-TM`]: https://mail.tm/
10
11use anyhow::{Context, Error};
12
13use token::Token;
14use accounts::Account;
15use tokio::time::Duration;
16use user::User;
17use crate::hydra::HydraCollection;
18use crate::domains::Domain;
19use crate::messages::Message;
20
21pub mod token;
22pub mod accounts;
23pub mod domains;
24pub mod messages;
25pub mod error;
26pub mod http;
27pub mod hydra;
28pub mod user;
29
30pub(crate) const MAIL_API_URL: &str = "https://api.mail.tm";
31pub(crate) const USER_AGENT: &str = "Reqwest; mail-tm-rs";
32
33
34/// Creates an account based on a user
35///
36/// This will make user of [`User`] to create an account.
37///
38/// # Example
39/// ```
40/// use mail_tm_rs::user::User;
41/// use mail_tm_rs::{create_account, update_token, token, domains};
42///
43/// #[tokio::main]
44/// async fn main() -> Result<(), Box<dyn std::error::Error>> {
45/// //let user = User::default().with_domain(&domains().await?.any().domain);
46/// //let create = create_account(&user).await?;
47/// //let user = update_token(&user, &token(&user).await?.token);
48/// Ok(())
49/// }
50/// ```
51pub async fn create_account(user: &User) -> Result<Account, Error> {
52 accounts::create(user).await
53}
54
55/// Retrieve an account
56///
57/// Retrieve an account by its id. This uses the [`User::email_token`] field to build the auth header.
58///
59/// # Example
60/// ```
61/// use mail_tm_rs::user::User;
62/// use mail_tm_rs::{create_account, get_account, update_token, token, domains};
63///
64/// #[tokio::main]
65/// async fn main() -> Result<(), Box<dyn std::error::Error>> {
66/// //let user = User::default().with_domain(&domains().await?.any().domain);
67/// //let account = create_account(&user).await?;
68/// //let user = update_token(&user, &token(&user).await?.token);
69/// //let account = get_account(&user, &account.id.unwrap()).await?;
70/// Ok(())
71/// }
72/// ```
73pub async fn get_account(user: &User, id: &str) -> Result<Account, Error> {
74 accounts::get(&user.email_token, id).await
75}
76
77/// Delete an account
78///
79/// Delete an account by its id. This uses the [`User::email_token`] field to build the auth header.
80///
81/// # Example
82/// ```
83/// use mail_tm_rs::user::User;
84/// use mail_tm_rs::{create_account, update_token, token, delete_account, domains};
85/// #[tokio::main]
86/// async fn main() -> Result<(), Box<dyn std::error::Error>> {
87/// //let user = User::default().with_domain(&domains().await?.any().domain);
88/// //let account = create_account(&user).await?;
89/// //let user = update_token(&user, &token(&user).await?.token);
90/// //delete_account(&user, &account.id.unwrap()).await?;
91/// Ok(())
92/// }
93/// ```
94pub async fn delete_account(user: &User, id: &str) -> Result<(), Error> {
95 accounts::delete(&user.email_token, id).await
96}
97
98/// Retrieve an account
99///
100/// This will retrieve the account belonging to the token holder
101///
102/// # Example
103/// ```
104/// use mail_tm_rs::user::User;
105/// use mail_tm_rs::{create_account, update_token, token, me, domains};
106///
107/// #[tokio::main]
108/// async fn main() -> Result<(), Box<dyn std::error::Error>> {
109/// //let user = User::default().with_domain(&domains().await?.any().domain);
110/// //let account = create_account(&user).await?;
111/// //let user = update_token(&user, &token(&user).await?.token);
112/// //let user = me(&user).await?;
113/// Ok(())
114/// }
115/// ```
116pub async fn me(user: &User) -> Result<Account, Error> {
117 accounts::me(&user.email_token).await
118}
119
120/// Retrieve all available domains
121///
122/// # Example
123/// ```
124/// use mail_tm_rs::user::User;
125/// use mail_tm_rs::{domains};
126///
127/// #[tokio::main]
128/// async fn main() -> Result<(), Box<dyn std::error::Error>> {
129/// let domains = domains().await?;
130/// Ok(())
131/// }
132/// ```
133pub async fn domains() -> Result<HydraCollection<Domain>, Error> {
134 domains::domains().await
135}
136
137/// List messages
138///
139/// This will list messages belonging to the token holder. Has a page for optional page selection(inclusive).
140/// Defaults to `1`
141///
142/// # Example
143/// ```
144/// use mail_tm_rs::user::User;
145/// use mail_tm_rs::{create_account, update_token, token, me, list_messages, domains};
146/// #[tokio::main]
147/// async fn main() -> Result<(), Box<dyn std::error::Error>> {
148/// //let user = User::default().with_domain(&domains().await?.any().domain);
149/// //let account = create_account(&user).await?;
150/// //let user = update_token(&user, &token(&user).await?.token);
151/// //let messages = list_messages(&user, Some(33)).await?;
152/// Ok(())
153/// }
154/// ```
155pub async fn list_messages(user: &User, page: Option<usize>) -> Result<HydraCollection<Message>, Error> {
156 messages::messages(&user.email_token, page).await
157}
158
159/// Get message
160///
161/// Retrieve a message by its id.
162///
163/// # Example
164/// ```
165/// use mail_tm_rs::user::User;
166/// use mail_tm_rs::{create_account, update_token, token, get_message, domains};
167/// #[tokio::main]
168/// async fn main() -> Result<(), Box<dyn std::error::Error>> {
169/// //let user = User::default().with_domain(&domains().await?.any().domain);
170/// //let account = create_account(&user).await?;
171/// //let user = update_token(&user, &token(&user).await?.token);
172/// //let messages = get_message(&user, "somemessageid").await?;
173/// Ok(())
174/// }
175/// ```
176pub async fn get_message(user: &User, id: &str) -> Result<Message, Error> {
177 messages::get(&user.email_token, id).await
178}
179
180/// Delete message
181///
182/// Delete a message by its id.
183///
184/// # Example
185/// ```
186/// use mail_tm_rs::user::User;
187/// use mail_tm_rs::{create_account, update_token, token, delete_message, domains};
188///
189/// #[tokio::main]
190/// async fn main() -> Result<(), Box<dyn std::error::Error>> {
191/// //let user = User::default().with_domain(&domains().await?.any().domain);
192/// //let account = create_account(&user).await?;
193/// //let user = update_token(&user, &token(&user).await?.token);
194/// //let messages = delete_message(&user, "somemessageid").await?;
195/// Ok(())
196/// }
197/// ```
198pub async fn delete_message(user: &User, id: &str) -> Result<(), Error> {
199 messages::delete(&user.email_token, id).await
200}
201
202/// Retrieve a token for a user
203///
204/// You should update each user's token by using `update_token`. In the future we will support both
205/// providing a raw token or a user.
206///
207/// # Example
208/// ```
209/// use mail_tm_rs::user::User;
210/// use mail_tm_rs::{create_account, update_token, token, domains};
211///
212/// #[tokio::main]
213/// async fn main() -> Result<(), Box<dyn std::error::Error>> {
214/// let user = User::default().with_domain(&domains().await?.any().domain);
215/// let account = create_account(&user).await?;
216/// let user = update_token(&user, &token(&user).await?.token);
217/// Ok(())
218/// }
219/// ```
220pub async fn token(user: &User) -> Result<Token, Error> {
221 token::token(user).await
222}
223
224/// Populates the email token on a user
225///
226/// This uses a simple builder like pattern. In the future we will support a zero-copy version too.
227///
228/// # Example
229/// ```
230/// use mail_tm_rs::user::User;
231/// use mail_tm_rs::{create_account, update_token, token, domains};
232///
233/// #[tokio::main]
234/// async fn main() -> Result<(), Box<dyn std::error::Error>> {
235/// let user = User::default().with_domain(&domains().await?.any().domain);
236/// let account = create_account(&user).await?;
237/// let user = update_token(&user, &token(&user).await?.token);
238/// Ok(())
239/// }
240/// ```
241pub fn update_token(user: &User, token: &str) -> User {
242 User {
243 email_token: token.to_string(),
244 ..user.clone()
245 }
246}
247
248macro_rules! bo {
249 ($e:expr) => {
250 tokio_test::block_on($e)
251 };
252}