Skip to main content

stalwart_lib/jmap-proto/src/request/
method.rs

1/*
2 * SPDX-FileCopyrightText: 2020 Stalwart Labs LLC <hello@stalw.art>
3 *
4 * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL
5 */
6
7use std::fmt::Display;
8
9#[derive(Debug, Clone, Copy, PartialEq, Eq)]
10pub struct MethodName {
11    pub obj: MethodObject,
12    pub fnc: MethodFunction,
13}
14
15#[derive(Debug, Clone, Copy, PartialEq, Eq)]
16pub enum MethodObject {
17    Email,
18    Mailbox,
19    Core,
20    Blob,
21    PushSubscription,
22    Thread,
23    SearchSnippet,
24    Identity,
25    EmailSubmission,
26    VacationResponse,
27    SieveScript,
28    Principal,
29    Quota,
30    Calendar,
31    CalendarEvent,
32    CalendarEventNotification,
33    AddressBook,
34    ContactCard,
35    FileNode,
36    ParticipantIdentity,
37    ShareNotification,
38}
39
40#[derive(Debug, Clone, Copy, PartialEq, Eq)]
41pub enum MethodFunction {
42    Get,
43    Set,
44    Changes,
45    Query,
46    QueryChanges,
47    Copy,
48    Import,
49    Parse,
50    Validate,
51    Lookup,
52    Upload,
53    Echo,
54    GetAvailability,
55}
56
57impl Display for MethodName {
58    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
59        f.write_str(self.as_str())
60    }
61}
62
63impl MethodName {
64    pub fn new(obj: MethodObject, fnc: MethodFunction) -> Self {
65        Self { obj, fnc }
66    }
67
68    pub fn error() -> Self {
69        Self {
70            obj: MethodObject::Thread,
71            fnc: MethodFunction::Echo,
72        }
73    }
74
75    pub fn as_str(&self) -> &'static str {
76        match (self.fnc, self.obj) {
77            (MethodFunction::Get, MethodObject::PushSubscription) => "PushSubscription/get",
78            (MethodFunction::Set, MethodObject::PushSubscription) => "PushSubscription/set",
79
80            (MethodFunction::Get, MethodObject::Mailbox) => "Mailbox/get",
81            (MethodFunction::Changes, MethodObject::Mailbox) => "Mailbox/changes",
82            (MethodFunction::Query, MethodObject::Mailbox) => "Mailbox/query",
83            (MethodFunction::QueryChanges, MethodObject::Mailbox) => "Mailbox/queryChanges",
84            (MethodFunction::Set, MethodObject::Mailbox) => "Mailbox/set",
85
86            (MethodFunction::Get, MethodObject::Thread) => "Thread/get",
87            (MethodFunction::Changes, MethodObject::Thread) => "Thread/changes",
88
89            (MethodFunction::Get, MethodObject::Email) => "Email/get",
90            (MethodFunction::Changes, MethodObject::Email) => "Email/changes",
91            (MethodFunction::Query, MethodObject::Email) => "Email/query",
92            (MethodFunction::QueryChanges, MethodObject::Email) => "Email/queryChanges",
93            (MethodFunction::Set, MethodObject::Email) => "Email/set",
94            (MethodFunction::Copy, MethodObject::Email) => "Email/copy",
95            (MethodFunction::Import, MethodObject::Email) => "Email/import",
96            (MethodFunction::Parse, MethodObject::Email) => "Email/parse",
97
98            (MethodFunction::Get, MethodObject::SearchSnippet) => "SearchSnippet/get",
99
100            (MethodFunction::Get, MethodObject::Identity) => "Identity/get",
101            (MethodFunction::Changes, MethodObject::Identity) => "Identity/changes",
102            (MethodFunction::Set, MethodObject::Identity) => "Identity/set",
103
104            (MethodFunction::Get, MethodObject::EmailSubmission) => "EmailSubmission/get",
105            (MethodFunction::Changes, MethodObject::EmailSubmission) => "EmailSubmission/changes",
106            (MethodFunction::Query, MethodObject::EmailSubmission) => "EmailSubmission/query",
107            (MethodFunction::QueryChanges, MethodObject::EmailSubmission) => {
108                "EmailSubmission/queryChanges"
109            }
110            (MethodFunction::Set, MethodObject::EmailSubmission) => "EmailSubmission/set",
111
112            (MethodFunction::Get, MethodObject::VacationResponse) => "VacationResponse/get",
113            (MethodFunction::Set, MethodObject::VacationResponse) => "VacationResponse/set",
114
115            (MethodFunction::Get, MethodObject::SieveScript) => "SieveScript/get",
116            (MethodFunction::Set, MethodObject::SieveScript) => "SieveScript/set",
117            (MethodFunction::Query, MethodObject::SieveScript) => "SieveScript/query",
118            (MethodFunction::Validate, MethodObject::SieveScript) => "SieveScript/validate",
119
120            (MethodFunction::Get, MethodObject::Principal) => "Principal/get",
121            (MethodFunction::Set, MethodObject::Principal) => "Principal/set",
122            (MethodFunction::Query, MethodObject::Principal) => "Principal/query",
123            (MethodFunction::Changes, MethodObject::Principal) => "Principal/changes",
124            (MethodFunction::QueryChanges, MethodObject::Principal) => "Principal/queryChanges",
125            (MethodFunction::GetAvailability, MethodObject::Principal) => {
126                "Principal/getAvailability"
127            }
128
129            (MethodFunction::Get, MethodObject::Quota) => "Quota/get",
130            (MethodFunction::Changes, MethodObject::Quota) => "Quota/changes",
131            (MethodFunction::Query, MethodObject::Quota) => "Quota/query",
132            (MethodFunction::QueryChanges, MethodObject::Quota) => "Quota/queryChanges",
133
134            (MethodFunction::Get, MethodObject::Blob) => "Blob/get",
135            (MethodFunction::Copy, MethodObject::Blob) => "Blob/copy",
136            (MethodFunction::Lookup, MethodObject::Blob) => "Blob/lookup",
137            (MethodFunction::Upload, MethodObject::Blob) => "Blob/upload",
138
139            (MethodFunction::Get, MethodObject::AddressBook) => "AddressBook/get",
140            (MethodFunction::Changes, MethodObject::AddressBook) => "AddressBook/changes",
141            (MethodFunction::Set, MethodObject::AddressBook) => "AddressBook/set",
142
143            (MethodFunction::Get, MethodObject::ContactCard) => "ContactCard/get",
144            (MethodFunction::Changes, MethodObject::ContactCard) => "ContactCard/changes",
145            (MethodFunction::Query, MethodObject::ContactCard) => "ContactCard/query",
146            (MethodFunction::QueryChanges, MethodObject::ContactCard) => "ContactCard/queryChanges",
147            (MethodFunction::Set, MethodObject::ContactCard) => "ContactCard/set",
148            (MethodFunction::Copy, MethodObject::ContactCard) => "ContactCard/copy",
149            (MethodFunction::Parse, MethodObject::ContactCard) => "ContactCard/parse",
150
151            (MethodFunction::Get, MethodObject::FileNode) => "FileNode/get",
152            (MethodFunction::Changes, MethodObject::FileNode) => "FileNode/changes",
153            (MethodFunction::Query, MethodObject::FileNode) => "FileNode/query",
154            (MethodFunction::QueryChanges, MethodObject::FileNode) => "FileNode/queryChanges",
155            (MethodFunction::Set, MethodObject::FileNode) => "FileNode/set",
156
157            (MethodFunction::Get, MethodObject::ShareNotification) => "ShareNotification/get",
158            (MethodFunction::Changes, MethodObject::ShareNotification) => {
159                "ShareNotification/changes"
160            }
161            (MethodFunction::Query, MethodObject::ShareNotification) => "ShareNotification/query",
162            (MethodFunction::QueryChanges, MethodObject::ShareNotification) => {
163                "ShareNotification/queryChanges"
164            }
165            (MethodFunction::Set, MethodObject::ShareNotification) => "ShareNotification/set",
166
167            (MethodFunction::Get, MethodObject::Calendar) => "Calendar/get",
168            (MethodFunction::Changes, MethodObject::Calendar) => "Calendar/changes",
169            (MethodFunction::Set, MethodObject::Calendar) => "Calendar/set",
170
171            (MethodFunction::Get, MethodObject::CalendarEvent) => "CalendarEvent/get",
172            (MethodFunction::Changes, MethodObject::CalendarEvent) => "CalendarEvent/changes",
173            (MethodFunction::Query, MethodObject::CalendarEvent) => "CalendarEvent/query",
174            (MethodFunction::QueryChanges, MethodObject::CalendarEvent) => {
175                "CalendarEvent/queryChanges"
176            }
177            (MethodFunction::Set, MethodObject::CalendarEvent) => "CalendarEvent/set",
178            (MethodFunction::Copy, MethodObject::CalendarEvent) => "CalendarEvent/copy",
179            (MethodFunction::Parse, MethodObject::CalendarEvent) => "CalendarEvent/parse",
180
181            (MethodFunction::Get, MethodObject::CalendarEventNotification) => {
182                "CalendarEventNotification/get"
183            }
184            (MethodFunction::Changes, MethodObject::CalendarEventNotification) => {
185                "CalendarEventNotification/changes"
186            }
187            (MethodFunction::Query, MethodObject::CalendarEventNotification) => {
188                "CalendarEventNotification/query"
189            }
190            (MethodFunction::QueryChanges, MethodObject::CalendarEventNotification) => {
191                "CalendarEventNotification/queryChanges"
192            }
193            (MethodFunction::Set, MethodObject::CalendarEventNotification) => {
194                "CalendarEventNotification/set"
195            }
196
197            (MethodFunction::Get, MethodObject::ParticipantIdentity) => "ParticipantIdentity/get",
198            (MethodFunction::Changes, MethodObject::ParticipantIdentity) => {
199                "ParticipantIdentity/changes"
200            }
201            (MethodFunction::Set, MethodObject::ParticipantIdentity) => "ParticipantIdentity/set",
202
203            (MethodFunction::Echo, MethodObject::Core) => "Core/echo",
204            _ => "error",
205        }
206    }
207
208    pub fn parse(s: &str) -> Option<Self> {
209        hashify::tiny_map!(s.as_bytes(),
210            "PushSubscription/get" => (MethodObject::PushSubscription, MethodFunction::Get),
211            "PushSubscription/set" => (MethodObject::PushSubscription, MethodFunction::Set),
212
213            "Mailbox/get" => (MethodObject::Mailbox, MethodFunction::Get),
214            "Mailbox/changes" => (MethodObject::Mailbox, MethodFunction::Changes),
215            "Mailbox/query" => (MethodObject::Mailbox, MethodFunction::Query),
216            "Mailbox/queryChanges" => (MethodObject::Mailbox, MethodFunction::QueryChanges),
217            "Mailbox/set" => (MethodObject::Mailbox, MethodFunction::Set),
218
219            "Thread/get" => (MethodObject::Thread, MethodFunction::Get),
220            "Thread/changes" => (MethodObject::Thread, MethodFunction::Changes),
221
222            "Email/get" => (MethodObject::Email, MethodFunction::Get),
223            "Email/changes" => (MethodObject::Email, MethodFunction::Changes),
224            "Email/query" => (MethodObject::Email, MethodFunction::Query),
225            "Email/queryChanges" => (MethodObject::Email, MethodFunction::QueryChanges),
226            "Email/set" => (MethodObject::Email, MethodFunction::Set),
227            "Email/copy" => (MethodObject::Email, MethodFunction::Copy),
228            "Email/import" => (MethodObject::Email, MethodFunction::Import),
229            "Email/parse" => (MethodObject::Email, MethodFunction::Parse),
230
231            "SearchSnippet/get" => (MethodObject::SearchSnippet, MethodFunction::Get),
232
233            "Identity/get" => (MethodObject::Identity, MethodFunction::Get),
234            "Identity/changes" => (MethodObject::Identity, MethodFunction::Changes),
235            "Identity/set" => (MethodObject::Identity, MethodFunction::Set),
236
237            "EmailSubmission/get" => (MethodObject::EmailSubmission, MethodFunction::Get),
238            "EmailSubmission/changes" => (MethodObject::EmailSubmission, MethodFunction::Changes),
239            "EmailSubmission/query" => (MethodObject::EmailSubmission, MethodFunction::Query),
240            "EmailSubmission/queryChanges" => (MethodObject::EmailSubmission, MethodFunction::QueryChanges),
241            "EmailSubmission/set" => (MethodObject::EmailSubmission, MethodFunction::Set),
242
243            "VacationResponse/get" => (MethodObject::VacationResponse, MethodFunction::Get),
244            "VacationResponse/set" => (MethodObject::VacationResponse, MethodFunction::Set),
245
246            "SieveScript/get" => (MethodObject::SieveScript, MethodFunction::Get),
247            "SieveScript/set" => (MethodObject::SieveScript, MethodFunction::Set),
248            "SieveScript/query" => (MethodObject::SieveScript, MethodFunction::Query),
249            "SieveScript/validate" => (MethodObject::SieveScript, MethodFunction::Validate),
250
251            "Principal/get" => (MethodObject::Principal, MethodFunction::Get),
252            "Principal/set" => (MethodObject::Principal, MethodFunction::Set),
253            "Principal/query" => (MethodObject::Principal, MethodFunction::Query),
254            "Principal/changes" => (MethodObject::Principal, MethodFunction::Changes),
255            "Principal/queryChanges" => (MethodObject::Principal, MethodFunction::QueryChanges),
256            "Principal/getAvailability" => (MethodObject::Principal, MethodFunction::GetAvailability),
257
258            "Quota/get" => (MethodObject::Quota, MethodFunction::Get),
259            "Quota/changes" => (MethodObject::Quota, MethodFunction::Changes),
260            "Quota/query" => (MethodObject::Quota, MethodFunction::Query),
261            "Quota/queryChanges" => (MethodObject::Quota, MethodFunction::QueryChanges),
262
263            "Blob/get" => (MethodObject::Blob, MethodFunction::Get),
264            "Blob/copy" => (MethodObject::Blob, MethodFunction::Copy),
265            "Blob/lookup" => (MethodObject::Blob, MethodFunction::Lookup),
266            "Blob/upload" => (MethodObject::Blob, MethodFunction::Upload),
267
268            "AddressBook/get" => (MethodObject::AddressBook, MethodFunction::Get),
269            "AddressBook/changes" => (MethodObject::AddressBook, MethodFunction::Changes),
270            "AddressBook/set" => (MethodObject::AddressBook, MethodFunction::Set),
271
272            "ContactCard/get" => (MethodObject::ContactCard, MethodFunction::Get),
273            "ContactCard/changes" => (MethodObject::ContactCard, MethodFunction::Changes),
274            "ContactCard/query" => (MethodObject::ContactCard, MethodFunction::Query),
275            "ContactCard/queryChanges" => (MethodObject::ContactCard, MethodFunction::QueryChanges),
276            "ContactCard/set" => (MethodObject::ContactCard, MethodFunction::Set),
277            "ContactCard/copy" => (MethodObject::ContactCard, MethodFunction::Copy),
278            "ContactCard/parse" => (MethodObject::ContactCard, MethodFunction::Parse),
279
280            "FileNode/get" => (MethodObject::FileNode, MethodFunction::Get),
281            "FileNode/changes" => (MethodObject::FileNode, MethodFunction::Changes),
282            "FileNode/query" => (MethodObject::FileNode, MethodFunction::Query),
283            "FileNode/queryChanges" => (MethodObject::FileNode, MethodFunction::QueryChanges),
284            "FileNode/set" => (MethodObject::FileNode, MethodFunction::Set),
285
286            "ShareNotification/get" => (MethodObject::ShareNotification, MethodFunction::Get),
287            "ShareNotification/changes" => (MethodObject::ShareNotification, MethodFunction::Changes),
288            "ShareNotification/set" => (MethodObject::ShareNotification, MethodFunction::Set),
289            "ShareNotification/query" => (MethodObject::ShareNotification, MethodFunction::Query),
290            "ShareNotification/queryChanges" => (MethodObject::ShareNotification, MethodFunction::QueryChanges),
291
292            "Calendar/get" => (MethodObject::Calendar, MethodFunction::Get),
293            "Calendar/changes" => (MethodObject::Calendar, MethodFunction::Changes),
294            "Calendar/set" => (MethodObject::Calendar, MethodFunction::Set),
295
296            "CalendarEvent/get" => (MethodObject::CalendarEvent, MethodFunction::Get),
297            "CalendarEvent/changes" => (MethodObject::CalendarEvent, MethodFunction::Changes),
298            "CalendarEvent/query" => (MethodObject::CalendarEvent, MethodFunction::Query),
299            "CalendarEvent/queryChanges" => (MethodObject::CalendarEvent, MethodFunction::QueryChanges),
300            "CalendarEvent/set" => (MethodObject::CalendarEvent, MethodFunction::Set),
301            "CalendarEvent/copy" => (MethodObject::CalendarEvent, MethodFunction::Copy),
302            "CalendarEvent/parse" => (MethodObject::CalendarEvent, MethodFunction::Parse),
303
304            "CalendarEventNotification/get" => (MethodObject::CalendarEventNotification, MethodFunction::Get),
305            "CalendarEventNotification/changes" => (MethodObject::CalendarEventNotification, MethodFunction::Changes),
306            "CalendarEventNotification/set" => (MethodObject::CalendarEventNotification, MethodFunction::Set),
307            "CalendarEventNotification/query" => (MethodObject::CalendarEventNotification, MethodFunction::Query),
308            "CalendarEventNotification/queryChanges" => (MethodObject::CalendarEventNotification, MethodFunction::QueryChanges),
309
310            "ParticipantIdentity/get" => (MethodObject::ParticipantIdentity, MethodFunction::Get),
311            "ParticipantIdentity/changes" => (MethodObject::ParticipantIdentity, MethodFunction::Changes),
312            "ParticipantIdentity/set" => (MethodObject::ParticipantIdentity, MethodFunction::Set),
313
314            "Core/echo" => (MethodObject::Core, MethodFunction::Echo),
315
316        ).map(|(obj, fnc)| MethodName { obj, fnc })
317    }
318}
319
320impl Display for MethodObject {
321    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
322        f.write_str(match self {
323            MethodObject::Blob => "Blob",
324            MethodObject::EmailSubmission => "EmailSubmission",
325            MethodObject::SearchSnippet => "SearchSnippet",
326            MethodObject::Identity => "Identity",
327            MethodObject::VacationResponse => "VacationResponse",
328            MethodObject::PushSubscription => "PushSubscription",
329            MethodObject::SieveScript => "SieveScript",
330            MethodObject::Principal => "Principal",
331            MethodObject::Core => "Core",
332            MethodObject::Mailbox => "Mailbox",
333            MethodObject::Thread => "Thread",
334            MethodObject::Email => "Email",
335            MethodObject::Quota => "Quota",
336            MethodObject::AddressBook => "AddressBook",
337            MethodObject::ContactCard => "ContactCard",
338            MethodObject::FileNode => "FileNode",
339            MethodObject::ParticipantIdentity => "ParticipantIdentity",
340            MethodObject::Calendar => "Calendar",
341            MethodObject::CalendarEvent => "CalendarEvent",
342            MethodObject::CalendarEventNotification => "CalendarEventNotification",
343            MethodObject::ShareNotification => "ShareNotification",
344        })
345    }
346}
347
348impl<'de> serde::Deserialize<'de> for MethodName {
349    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
350    where
351        D: serde::Deserializer<'de>,
352    {
353        let value = <&str>::deserialize(deserializer)?;
354
355        MethodName::parse(value)
356            .ok_or_else(|| serde::de::Error::custom(format!("Invalid method name: {:?}", value)))
357    }
358}
359
360impl serde::Serialize for MethodName {
361    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
362    where
363        S: serde::Serializer,
364    {
365        serializer.serialize_str(self.as_str())
366    }
367}