1use anyhow::{Context, Error};
2use serde::{Deserialize, Serialize};
3
4use crate::{http, MAIL_API_URL};
5use crate::http::{Client, get_headers};
6use crate::hydra::{HydraCollection, Search, View};
7
8#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
9#[serde(rename_all = "camelCase")]
10pub struct Messages {
11 #[serde(rename = "hydra:member")]
12 pub messages: Vec<Message>,
13 #[serde(rename = "hydra:totalItems")]
14 pub total_items: i64,
15 #[serde(rename = "hydra:view")]
16 pub view: Option<View>,
17 #[serde(rename = "hydra:search")]
18 pub search: Option<Search>,
19}
20
21#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
22#[serde(rename_all = "camelCase")]
23pub struct Message {
24 #[serde(rename = "@context")]
25 pub context: String,
26 #[serde(rename = "@id")]
27 pub id: String,
28 #[serde(rename = "@type")]
29 pub type_field: String,
30 #[serde(rename = "id")]
31 pub id2: String,
32 #[serde(rename = "account_id")]
33 pub account_id: String,
34 #[serde(rename = "msgid")]
35 pub msg_id: String,
36 pub from: From,
37 pub to: Vec<To>,
38 pub cc: Vec<::serde_json::Value>,
39 pub bcc: Vec<::serde_json::Value>,
40 pub subject: String,
41 pub seen: bool,
42 pub flagged: bool,
43 #[serde(rename = "verification_results")]
44 pub verification_results: Vec<::serde_json::Value>,
45 pub retention: bool,
46 #[serde(rename = "retention_date")]
47 pub retention_date: i64,
48 pub text: String,
49 pub html: Vec<String>,
50 #[serde(rename = "has_attachments")]
51 pub has_attachments: bool,
52 pub attachments: Vec<::serde_json::Value>,
53 #[serde(rename = "download_url")]
54 pub download_url: String,
55 pub size: i64,
56 #[serde(rename = "created_at")]
57 pub created_at: String,
58 #[serde(rename = "updated_at")]
59 pub updated_at: String,
60}
61
62#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
63#[serde(rename_all = "camelCase")]
64pub struct From {
65 pub address: String,
66 pub name: String,
67}
68
69#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
70#[serde(rename_all = "camelCase")]
71pub struct To {
72 pub address: String,
73 pub name: String,
74}
75
76pub(crate) async fn messages(token: &str, page: Option<usize>) -> Result<HydraCollection<Message>, Error> {
77 let client = Client::new()?.with_auth(&token)?.build()?;
78
79 log::debug!("Getting messages");
80
81 let builder = client
82 .get(&format!("{}/messages", MAIL_API_URL));
83 let builder = if let Some(idx) = page {
84 builder.query(&("page", idx))
85 } else {
86 builder
87 };
88
89 let response = builder
90 .send()
91 .await?;
92
93 let code = response.status();
94
95 let response = response
96 .text()
97 .await?;
98
99 http::check_response_status(&code, &response).await?;
100
101 log::trace!("Retrieved domains: {}", response);
102 Ok(serde_json::from_str(&response)?)
103}
104
105pub(crate) async fn get(token: &str, id: &str) -> Result<Message, Error> {
106 let client = Client::new()?.with_auth(&token)?.build()?;
107
108 log::debug!("Searching for message with id {}", id);
109
110
111 let response = client
112 .get(&format!("{}/messages/{}", MAIL_API_URL, id))
113 .send()
114 .await?;
115
116 let code = response.status();
117
118 let response = response
119 .text()
120 .await?;
121
122 http::check_response_status(&code, &response).await?;
123
124 log::trace!("Retrieved a message: {}", response);
125 Ok(serde_json::from_str(&response)?)
126}
127
128
129pub(crate) async fn delete(token: &str, id: &str) -> Result<(), Error> {
130 let client = Client::new()?.with_auth(&token)?.build()?;
131
132 log::debug!("Searching for account with id {}", id);
133
134
135 let response = client
136 .delete(&format!("{}/messages/{}", MAIL_API_URL, id))
137 .send()
138 .await?;
139
140 let code = response.status();
141
142 http::check_response_status(&code, "").await?;
143
144 log::trace!("Deleted user with id {}", id);
145 Ok(())
146}
147
148pub(crate) async fn patch(token: &str, id: &str) -> Result<(), Error> {
150 let client = Client::new()?.with_auth(&token)?.build()?;
151
152 Ok(())
153}
154
155#[cfg(test)]
156mod tests {
157 use crate::accounts;
158 use crate::accounts::create;
159 use crate::user::User;
160
161 use super::*;
162
163 #[tokio::test]
164 async fn test_messages() -> Result<(), Error> {
165 pretty_env_logger::try_init().ok();
166 let user = User::default().with_domain(&crate::domains::domains().await?.any().domain);
167 let create = create(&user).await.unwrap();
168 let token = crate::token(&user).await.unwrap();
169
170
171 let messages = messages(&token.token, None).await?;
172 assert_eq!(messages.total_items, 0);
173
174 let id = create.id.unwrap();
175
176 accounts::delete(&token.token, &id).await.unwrap();
177
178 Ok(())
179 }
180
181 }