Skip to main content

rusmes_jmap/methods/submission/
types.rs

1//! JMAP EmailSubmission public types
2
3use chrono::{DateTime, Utc};
4use serde::{Deserialize, Serialize};
5use std::collections::HashMap;
6
7/// Email submission object
8#[derive(Debug, Clone, Serialize, Deserialize)]
9#[serde(rename_all = "camelCase")]
10pub struct EmailSubmission {
11    /// Unique identifier
12    pub id: String,
13    /// Identity ID for sender
14    pub identity_id: String,
15    /// Email ID being submitted
16    pub email_id: String,
17    /// Thread ID
18    #[serde(skip_serializing_if = "Option::is_none")]
19    pub thread_id: Option<String>,
20    /// Envelope information
21    #[serde(skip_serializing_if = "Option::is_none")]
22    pub envelope: Option<Envelope>,
23    /// Send at time (for delayed send)
24    #[serde(skip_serializing_if = "Option::is_none")]
25    pub send_at: Option<DateTime<Utc>>,
26    /// Undo status
27    pub undo_status: UndoStatus,
28    /// Delivery status
29    #[serde(skip_serializing_if = "Option::is_none")]
30    pub delivery_status: Option<HashMap<String, DeliveryStatus>>,
31    /// DSN blob IDs
32    #[serde(skip_serializing_if = "Option::is_none")]
33    pub dsn_blob_ids: Option<Vec<String>>,
34    /// MDN blob IDs
35    #[serde(skip_serializing_if = "Option::is_none")]
36    pub mdn_blob_ids: Option<Vec<String>>,
37}
38
39/// Envelope for submission
40#[derive(Debug, Clone, Serialize, Deserialize)]
41#[serde(rename_all = "camelCase")]
42pub struct Envelope {
43    pub mail_from: Address,
44    pub rcpt_to: Vec<Address>,
45}
46
47/// Email address for envelope
48#[derive(Debug, Clone, Serialize, Deserialize)]
49#[serde(rename_all = "camelCase")]
50pub struct Address {
51    pub email: String,
52    #[serde(skip_serializing_if = "Option::is_none")]
53    pub parameters: Option<HashMap<String, Option<String>>>,
54}
55
56/// Undo status enum
57#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
58#[serde(rename_all = "camelCase")]
59pub enum UndoStatus {
60    Pending,
61    Final,
62    Canceled,
63}
64
65/// Delivery status for a recipient
66#[derive(Debug, Clone, Serialize, Deserialize)]
67#[serde(rename_all = "camelCase")]
68pub struct DeliveryStatus {
69    pub smtp_reply: String,
70    pub delivered: DeliveryState,
71    pub displayed: DisplayedState,
72}
73
74/// Delivery state enum
75#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
76#[serde(rename_all = "camelCase")]
77pub enum DeliveryState {
78    Queued,
79    Yes,
80    No,
81    Unknown,
82}
83
84/// Displayed state enum
85#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
86#[serde(rename_all = "camelCase")]
87pub enum DisplayedState {
88    Unknown,
89    Yes,
90    No,
91}
92
93/// EmailSubmission/get request
94#[derive(Debug, Clone, Deserialize)]
95#[serde(rename_all = "camelCase")]
96pub struct EmailSubmissionGetRequest {
97    pub account_id: String,
98    #[serde(skip_serializing_if = "Option::is_none")]
99    pub ids: Option<Vec<String>>,
100    #[serde(skip_serializing_if = "Option::is_none")]
101    pub properties: Option<Vec<String>>,
102}
103
104/// EmailSubmission/get response
105#[derive(Debug, Clone, Serialize)]
106#[serde(rename_all = "camelCase")]
107pub struct EmailSubmissionGetResponse {
108    pub account_id: String,
109    pub state: String,
110    pub list: Vec<EmailSubmission>,
111    pub not_found: Vec<String>,
112}
113
114/// EmailSubmission/set request
115#[derive(Debug, Clone, Deserialize)]
116#[serde(rename_all = "camelCase")]
117pub struct EmailSubmissionSetRequest {
118    pub account_id: String,
119    #[serde(skip_serializing_if = "Option::is_none")]
120    pub if_in_state: Option<String>,
121    #[serde(skip_serializing_if = "Option::is_none")]
122    pub create: Option<HashMap<String, EmailSubmissionObject>>,
123    #[serde(skip_serializing_if = "Option::is_none")]
124    pub update: Option<HashMap<String, serde_json::Value>>,
125    #[serde(skip_serializing_if = "Option::is_none")]
126    pub destroy: Option<Vec<String>>,
127    #[serde(skip_serializing_if = "Option::is_none")]
128    pub on_success_update_email: Option<HashMap<String, serde_json::Value>>,
129    #[serde(skip_serializing_if = "Option::is_none")]
130    pub on_success_destroy_email: Option<Vec<String>>,
131}
132
133/// EmailSubmission object for creation
134#[derive(Debug, Clone, Deserialize)]
135#[serde(rename_all = "camelCase")]
136pub struct EmailSubmissionObject {
137    pub identity_id: String,
138    pub email_id: String,
139    #[serde(skip_serializing_if = "Option::is_none")]
140    pub envelope: Option<Envelope>,
141    #[serde(skip_serializing_if = "Option::is_none")]
142    pub send_at: Option<DateTime<Utc>>,
143}
144
145/// EmailSubmission/set response
146#[derive(Debug, Clone, Serialize)]
147#[serde(rename_all = "camelCase")]
148pub struct EmailSubmissionSetResponse {
149    pub account_id: String,
150    pub old_state: String,
151    pub new_state: String,
152    #[serde(skip_serializing_if = "Option::is_none")]
153    pub created: Option<HashMap<String, EmailSubmission>>,
154    #[serde(skip_serializing_if = "Option::is_none")]
155    pub updated: Option<HashMap<String, Option<EmailSubmission>>>,
156    #[serde(skip_serializing_if = "Option::is_none")]
157    pub destroyed: Option<Vec<String>>,
158    #[serde(skip_serializing_if = "Option::is_none")]
159    pub not_created: Option<HashMap<String, crate::types::JmapSetError>>,
160    #[serde(skip_serializing_if = "Option::is_none")]
161    pub not_updated: Option<HashMap<String, crate::types::JmapSetError>>,
162    #[serde(skip_serializing_if = "Option::is_none")]
163    pub not_destroyed: Option<HashMap<String, crate::types::JmapSetError>>,
164}
165
166/// EmailSubmission/query request
167#[derive(Debug, Clone, Deserialize)]
168#[serde(rename_all = "camelCase")]
169pub struct EmailSubmissionQueryRequest {
170    pub account_id: String,
171    #[serde(skip_serializing_if = "Option::is_none")]
172    pub filter: Option<EmailSubmissionFilterCondition>,
173    #[serde(skip_serializing_if = "Option::is_none")]
174    pub sort: Option<Vec<EmailSubmissionSort>>,
175    #[serde(skip_serializing_if = "Option::is_none")]
176    pub position: Option<i64>,
177    #[serde(skip_serializing_if = "Option::is_none")]
178    pub limit: Option<u64>,
179    #[serde(skip_serializing_if = "Option::is_none")]
180    pub calculate_total: Option<bool>,
181}
182
183/// EmailSubmission filter condition
184#[derive(Debug, Clone, Deserialize)]
185#[serde(rename_all = "camelCase")]
186pub struct EmailSubmissionFilterCondition {
187    #[serde(skip_serializing_if = "Option::is_none")]
188    pub identity_ids: Option<Vec<String>>,
189    #[serde(skip_serializing_if = "Option::is_none")]
190    pub email_ids: Option<Vec<String>>,
191    #[serde(skip_serializing_if = "Option::is_none")]
192    pub thread_ids: Option<Vec<String>>,
193    #[serde(skip_serializing_if = "Option::is_none")]
194    pub undo_status: Option<UndoStatus>,
195    #[serde(skip_serializing_if = "Option::is_none")]
196    pub before: Option<DateTime<Utc>>,
197    #[serde(skip_serializing_if = "Option::is_none")]
198    pub after: Option<DateTime<Utc>>,
199}
200
201/// EmailSubmission sort comparator
202#[derive(Debug, Clone, Deserialize)]
203#[serde(rename_all = "camelCase")]
204pub struct EmailSubmissionSort {
205    pub property: String,
206    #[serde(skip_serializing_if = "Option::is_none")]
207    pub is_ascending: Option<bool>,
208}
209
210/// EmailSubmission/query response
211#[derive(Debug, Clone, Serialize)]
212#[serde(rename_all = "camelCase")]
213pub struct EmailSubmissionQueryResponse {
214    pub account_id: String,
215    pub query_state: String,
216    pub can_calculate_changes: bool,
217    pub position: i64,
218    pub ids: Vec<String>,
219    #[serde(skip_serializing_if = "Option::is_none")]
220    pub total: Option<u64>,
221    #[serde(skip_serializing_if = "Option::is_none")]
222    pub limit: Option<u64>,
223}
224
225/// EmailSubmission/changes request
226#[derive(Debug, Clone, Deserialize)]
227#[serde(rename_all = "camelCase")]
228pub struct EmailSubmissionChangesRequest {
229    pub account_id: String,
230    pub since_state: String,
231    #[serde(skip_serializing_if = "Option::is_none")]
232    pub max_changes: Option<u64>,
233}
234
235/// EmailSubmission/changes response
236#[derive(Debug, Clone, Serialize)]
237#[serde(rename_all = "camelCase")]
238pub struct EmailSubmissionChangesResponse {
239    pub account_id: String,
240    pub old_state: String,
241    pub new_state: String,
242    pub has_more_changes: bool,
243    pub created: Vec<String>,
244    pub updated: Vec<String>,
245    pub destroyed: Vec<String>,
246}