1use alloc::{string::String, vec::Vec};
7
8use base64::{Engine, engine::general_purpose::URL_SAFE_NO_PAD};
9use serde::{Deserialize, Serialize};
10
11pub mod attachments;
12pub mod batch_delete;
13pub mod batch_modify;
14pub mod delete;
15pub mod get;
16pub mod import;
17pub mod insert;
18pub mod list;
19pub mod modify;
20pub mod send;
21pub mod trash;
22pub mod untrash;
23
24#[derive(Debug, Clone, Default, Deserialize, Serialize, Eq, PartialEq)]
29#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
30#[serde(rename_all = "camelCase")]
31pub struct GmailMessage {
32 #[serde(default, skip_serializing_if = "String::is_empty")]
34 pub id: String,
35 #[serde(default, skip_serializing_if = "Option::is_none")]
37 pub thread_id: Option<String>,
38 #[serde(default, skip_serializing_if = "Vec::is_empty")]
40 pub label_ids: Vec<String>,
41 #[serde(default, skip_serializing_if = "Option::is_none")]
44 pub internal_date: Option<String>,
45 #[serde(default, skip_serializing_if = "Option::is_none")]
47 pub snippet: Option<String>,
48 #[serde(default, skip_serializing_if = "Option::is_none")]
50 pub payload: Option<GmailMessagePayload>,
51 #[serde(default, skip_serializing_if = "Option::is_none")]
53 pub raw: Option<String>,
54 #[serde(default, skip_serializing_if = "Option::is_none")]
56 pub size_estimate: Option<u64>,
57 #[serde(default, skip_serializing_if = "Option::is_none")]
59 pub history_id: Option<String>,
60}
61
62pub fn decode_raw(raw: &str) -> Result<Vec<u8>, base64::DecodeError> {
68 let normalized: String = raw.chars().filter(|c| !c.is_ascii_whitespace()).collect();
69 let normalized = normalized.trim_end_matches('=');
70 URL_SAFE_NO_PAD.decode(normalized)
71}
72
73pub fn encode_raw(raw: &[u8]) -> String {
76 URL_SAFE_NO_PAD.encode(raw)
77}
78
79#[derive(Debug, Clone, Default, Deserialize, Serialize, Eq, PartialEq)]
81#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
82#[serde(rename_all = "camelCase")]
83pub struct GmailMessageId {
84 pub id: String,
86 #[serde(default, skip_serializing_if = "Option::is_none")]
88 pub thread_id: Option<String>,
89}
90
91#[derive(Debug, Clone, Default, Deserialize, Serialize, Eq, PartialEq)]
96#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
97#[serde(rename_all = "camelCase")]
98pub struct GmailMessagePayload {
99 #[serde(default)]
101 pub part_id: Option<String>,
102 #[serde(default)]
104 pub mime_type: Option<String>,
105 #[serde(default)]
108 pub body: Option<GmailMessagePartBody>,
109 #[serde(default)]
112 pub filename: String,
113 #[serde(default)]
115 pub headers: Vec<GmailMessageHeader>,
116 #[serde(default)]
118 pub parts: Vec<GmailMessagePayload>,
119}
120
121impl GmailMessagePayload {
122 pub fn header(&self, name: &str) -> Option<&str> {
125 self.headers
126 .iter()
127 .find(|header| header.name.eq_ignore_ascii_case(name))
128 .map(|header| header.value.as_str())
129 }
130}
131
132#[derive(Debug, Clone, Default, Deserialize, Serialize, Eq, PartialEq)]
134#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
135#[serde(rename_all = "camelCase")]
136pub struct GmailMessagePartBody {
137 #[serde(default)]
140 pub attachment_id: Option<String>,
141 #[serde(default)]
143 pub size: u32,
144 #[serde(default)]
147 pub data: Option<String>,
148}
149
150#[derive(Debug, Clone, Deserialize, Serialize, Eq, PartialEq)]
152#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
153pub struct GmailMessageHeader {
154 pub name: String,
156 pub value: String,
158}
159
160#[derive(Debug, Clone, Copy, Deserialize, Serialize, Eq, PartialEq)]
162#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
163pub enum GmailMessageFormat {
164 Minimal,
167 Full,
170 Raw,
173 Metadata,
175}
176
177#[derive(Debug, Clone, Copy, Deserialize, Serialize, Eq, PartialEq)]
179#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
180#[serde(rename_all = "camelCase")]
181pub enum GmailMessageListVisibility {
182 Show,
184 Hide,
186}
187
188#[derive(Debug, Clone, Copy, Deserialize, Serialize, Eq, PartialEq)]
191#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
192pub enum GmailInternalDateSource {
193 ReceivedTime,
195 DateHeader,
197}