jmap_client/email_submission/
mod.rs

1/*
2 * Copyright Stalwart Labs LLC See the COPYING
3 * file at the top-level directory of this distribution.
4 *
5 * Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 * https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 * <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
8 * option. This file may not be copied, modified, or distributed
9 * except according to those terms.
10 */
11
12pub mod get;
13pub mod helpers;
14pub mod query;
15pub mod set;
16
17use ahash::AHashMap;
18use chrono::{DateTime, Utc};
19use serde::{Deserialize, Serialize};
20use std::fmt::Display;
21
22use crate::{
23    core::{changes::ChangesObject, Object},
24    email::Email,
25    Get, Set,
26};
27
28#[derive(Debug, Clone, Serialize, Default)]
29pub struct SetArguments {
30    #[serde(rename = "onSuccessUpdateEmail")]
31    #[serde(skip_serializing_if = "Option::is_none")]
32    on_success_update_email: Option<AHashMap<String, Email<Set>>>,
33    #[serde(rename = "onSuccessDestroyEmail")]
34    #[serde(skip_serializing_if = "Option::is_none")]
35    on_success_destroy_email: Option<Vec<String>>,
36}
37
38#[derive(Debug, Clone, Serialize, Deserialize)]
39pub struct EmailSubmission<State = Get> {
40    #[serde(skip)]
41    _create_id: Option<usize>,
42
43    #[serde(skip)]
44    _state: std::marker::PhantomData<State>,
45
46    #[serde(rename = "id")]
47    #[serde(skip_serializing_if = "Option::is_none")]
48    id: Option<String>,
49
50    #[serde(rename = "identityId")]
51    #[serde(skip_serializing_if = "Option::is_none")]
52    identity_id: Option<String>,
53
54    #[serde(rename = "emailId")]
55    #[serde(skip_serializing_if = "Option::is_none")]
56    email_id: Option<String>,
57
58    #[serde(rename = "threadId")]
59    #[serde(skip_serializing_if = "Option::is_none")]
60    thread_id: Option<String>,
61
62    #[serde(rename = "envelope")]
63    #[serde(skip_serializing_if = "Option::is_none")]
64    envelope: Option<Envelope>,
65
66    #[serde(rename = "sendAt")]
67    #[serde(skip_serializing_if = "Option::is_none")]
68    send_at: Option<DateTime<Utc>>,
69
70    #[serde(rename = "undoStatus")]
71    #[serde(skip_serializing_if = "Option::is_none")]
72    undo_status: Option<UndoStatus>,
73
74    #[serde(rename = "deliveryStatus")]
75    #[serde(skip_serializing_if = "Option::is_none")]
76    delivery_status: Option<AHashMap<String, DeliveryStatus>>,
77
78    #[serde(rename = "dsnBlobIds")]
79    #[serde(skip_serializing_if = "Option::is_none")]
80    dsn_blob_ids: Option<Vec<String>>,
81
82    #[serde(rename = "mdnBlobIds")]
83    #[serde(skip_serializing_if = "Option::is_none")]
84    mdn_blob_ids: Option<Vec<String>>,
85}
86
87#[derive(Debug, Clone, Serialize, Deserialize)]
88pub struct Envelope {
89    #[serde(rename = "mailFrom")]
90    mail_from: Address,
91
92    #[serde(rename = "rcptTo")]
93    rcpt_to: Vec<Address>,
94}
95
96#[derive(Debug, Clone, Serialize, Deserialize)]
97pub struct Address<State = Get> {
98    #[serde(skip)]
99    _state: std::marker::PhantomData<State>,
100
101    email: String,
102    parameters: Option<AHashMap<String, Option<String>>>,
103}
104
105#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
106pub enum UndoStatus {
107    #[serde(rename = "pending")]
108    Pending,
109    #[serde(rename = "final")]
110    Final,
111    #[serde(rename = "canceled")]
112    Canceled,
113}
114
115#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
116pub struct DeliveryStatus {
117    #[serde(rename = "smtpReply")]
118    smtp_reply: String,
119
120    #[serde(rename = "delivered")]
121    delivered: Delivered,
122
123    #[serde(rename = "displayed")]
124    displayed: Displayed,
125}
126
127#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
128pub enum Delivered {
129    #[serde(rename = "queued")]
130    Queued,
131    #[serde(rename = "yes")]
132    Yes,
133    #[serde(rename = "no")]
134    No,
135    #[serde(rename = "unknown")]
136    Unknown,
137}
138
139#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
140pub enum Displayed {
141    #[serde(rename = "unknown")]
142    Unknown,
143    #[serde(rename = "yes")]
144    Yes,
145}
146
147#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash, Copy)]
148pub enum Property {
149    #[serde(rename = "id")]
150    Id,
151    #[serde(rename = "identityId")]
152    IdentityId,
153    #[serde(rename = "emailId")]
154    EmailId,
155    #[serde(rename = "threadId")]
156    ThreadId,
157    #[serde(rename = "envelope")]
158    Envelope,
159    #[serde(rename = "sendAt")]
160    SendAt,
161    #[serde(rename = "undoStatus")]
162    UndoStatus,
163    #[serde(rename = "deliveryStatus")]
164    DeliveryStatus,
165    #[serde(rename = "dsnBlobIds")]
166    DsnBlobIds,
167    #[serde(rename = "mdnBlobIds")]
168    MdnBlobIds,
169}
170
171impl Display for Property {
172    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
173        match self {
174            Property::Id => write!(f, "id"),
175            Property::IdentityId => write!(f, "identityId"),
176            Property::EmailId => write!(f, "emailId"),
177            Property::ThreadId => write!(f, "threadId"),
178            Property::Envelope => write!(f, "envelope"),
179            Property::SendAt => write!(f, "sendAt"),
180            Property::UndoStatus => write!(f, "undoStatus"),
181            Property::DeliveryStatus => write!(f, "deliveryStatus"),
182            Property::DsnBlobIds => write!(f, "dsnBlobIds"),
183            Property::MdnBlobIds => write!(f, "mdnBlobIds"),
184        }
185    }
186}
187
188impl Object for EmailSubmission<Set> {
189    type Property = Property;
190
191    fn requires_account_id() -> bool {
192        true
193    }
194}
195
196impl Object for EmailSubmission<Get> {
197    type Property = Property;
198
199    fn requires_account_id() -> bool {
200        true
201    }
202}
203
204impl ChangesObject for EmailSubmission<Set> {
205    type ChangesResponse = ();
206}
207
208impl ChangesObject for EmailSubmission<Get> {
209    type ChangesResponse = ();
210}