Skip to main content

az_gmail_code/
model.rs

1use serde::{Deserialize, Serialize};
2use serde_json::Value;
3use std::collections::BTreeMap;
4
5/// Verification code extracted from a Gmail message.
6#[derive(Debug, Clone, PartialEq, Eq)]
7pub struct ExtractedGmailCode {
8    /// Numeric verification code.
9    pub code: String,
10    /// Gmail message id containing the code.
11    pub message_id: String,
12    /// Optional thread id returned by Gmail.
13    pub thread_id: Option<String>,
14    /// Best-effort sender header.
15    pub from: Option<String>,
16    /// Best-effort subject header.
17    pub subject: Option<String>,
18    /// MIME type of the body candidate that produced the code.
19    pub source_mime_type: String,
20}
21
22#[derive(Debug, Clone, PartialEq, Eq, Deserialize)]
23pub(crate) struct GmailListMessagesResponse {
24    #[serde(default)]
25    pub(crate) messages: Vec<GmailMessageSummary>,
26    #[serde(default, rename = "nextPageToken")]
27    pub(crate) next_page_token: Option<String>,
28    #[serde(default, rename = "resultSizeEstimate")]
29    pub(crate) result_size_estimate: Option<u32>,
30}
31
32#[derive(Debug, Clone, PartialEq, Eq, Deserialize)]
33pub(crate) struct GmailMessageSummary {
34    pub(crate) id: String,
35    #[serde(default, rename = "threadId")]
36    pub(crate) thread_id: Option<String>,
37}
38
39/// Gmail message shape needed for verification-code extraction.
40#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
41pub struct GmailMessage {
42    /// Gmail message id.
43    pub id: String,
44    /// Optional Gmail thread id.
45    #[serde(default, rename = "threadId")]
46    pub thread_id: Option<String>,
47    /// MIME tree root.
48    #[serde(default)]
49    pub payload: Option<GmailMessagePart>,
50    /// Short text snippet returned by Gmail.
51    #[serde(default)]
52    pub snippet: Option<String>,
53    /// Extra Gmail fields not modeled by this crate.
54    #[serde(flatten)]
55    pub extra: BTreeMap<String, Value>,
56}
57
58impl GmailMessage {
59    /// Returns a header value from the root payload, case-insensitively.
60    #[must_use]
61    pub fn header(&self, name: &str) -> Option<&str> {
62        self.payload.as_ref()?.header(name)
63    }
64}
65
66/// One part of a Gmail MIME message tree.
67#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
68pub struct GmailMessagePart {
69    /// Gmail part id.
70    #[serde(default, rename = "partId")]
71    pub part_id: Option<String>,
72    /// MIME type, for example `text/plain` or `text/html`.
73    #[serde(default, rename = "mimeType")]
74    pub mime_type: String,
75    /// Message headers for this part.
76    #[serde(default)]
77    pub headers: Vec<GmailMessageHeader>,
78    /// Body metadata and inline payload.
79    #[serde(default)]
80    pub body: Option<GmailMessagePartBody>,
81    /// Child MIME parts.
82    #[serde(default)]
83    pub parts: Vec<GmailMessagePart>,
84}
85
86impl GmailMessagePart {
87    /// Returns a header value from this part, case-insensitively.
88    #[must_use]
89    pub fn header(&self, name: &str) -> Option<&str> {
90        self.headers
91            .iter()
92            .find(|header| header.name.eq_ignore_ascii_case(name))
93            .map(|header| header.value.as_str())
94    }
95}
96
97/// Gmail MIME header.
98#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
99pub struct GmailMessageHeader {
100    /// Header name.
101    pub name: String,
102    /// Header value.
103    pub value: String,
104}
105
106/// Gmail message body metadata and inline payload.
107#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
108pub struct GmailMessagePartBody {
109    #[serde(default)]
110    pub data: Option<String>,
111    #[serde(default)]
112    pub size: Option<u64>,
113    #[serde(default, rename = "attachmentId")]
114    pub attachment_id: Option<String>,
115}