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}