1#[forbid(unsafe_code)]
184pub mod blob;
185pub mod client;
186pub mod core;
187pub mod email;
188pub mod email_submission;
189#[cfg(feature = "async")]
190pub mod event_source;
191pub mod identity;
192pub mod mailbox;
193pub mod principal;
194pub mod push_subscription;
195pub mod sieve;
196pub mod thread;
197pub mod vacation_response;
198
199use crate::core::error::MethodError;
200use crate::core::error::ProblemDetails;
201use crate::core::set::SetError;
202use ahash::AHashMap;
203use serde::{Deserialize, Serialize};
204use std::fmt::Display;
205
206#[cfg(feature = "websockets")]
207pub mod client_ws;
208
209#[derive(Debug, Clone, Serialize, Deserialize, Hash, PartialEq, Eq)]
210pub enum URI {
211 #[serde(rename = "urn:ietf:params:jmap:core")]
212 Core,
213 #[serde(rename = "urn:ietf:params:jmap:mail")]
214 Mail,
215 #[serde(rename = "urn:ietf:params:jmap:submission")]
216 Submission,
217 #[serde(rename = "urn:ietf:params:jmap:vacationresponse")]
218 VacationResponse,
219 #[serde(rename = "urn:ietf:params:jmap:contacts")]
220 Contacts,
221 #[serde(rename = "urn:ietf:params:jmap:calendars")]
222 Calendars,
223 #[serde(rename = "urn:ietf:params:jmap:websocket")]
224 WebSocket,
225 #[serde(rename = "urn:ietf:params:jmap:sieve")]
226 Sieve,
227 #[serde(rename = "urn:ietf:params:jmap:blob")]
228 Blob,
229 #[serde(rename = "urn:ietf:params:jmap:quota")]
230 Quota,
231 #[serde(rename = "urn:ietf:params:jmap:principals")]
232 Principals,
233 #[serde(rename = "urn:ietf:params:jmap:principals:owner")]
234 PrincipalsOwner,
235}
236
237impl AsRef<str> for URI {
238 fn as_ref(&self) -> &str {
239 match self {
240 URI::Core => "urn:ietf:params:jmap:core",
241 URI::Mail => "urn:ietf:params:jmap:mail",
242 URI::Submission => "urn:ietf:params:jmap:submission",
243 URI::VacationResponse => "urn:ietf:params:jmap:vacationresponse",
244 URI::Contacts => "urn:ietf:params:jmap:contacts",
245 URI::Calendars => "urn:ietf:params:jmap:calendars",
246 URI::WebSocket => "urn:ietf:params:jmap:websocket",
247 URI::Sieve => "urn:ietf:params:jmap:sieve",
248 URI::Blob => "urn:ietf:params:jmap:blob",
249 URI::Quota => "urn:ietf:params:jmap:quota",
250 URI::Principals => "urn:ietf:params:jmap:principals",
251 URI::PrincipalsOwner => "urn:ietf:params:jmap:principals:owner",
252 }
253 }
254}
255
256#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
257pub enum Method {
258 #[serde(rename = "Core/echo")]
259 Echo,
260 #[serde(rename = "Blob/copy")]
261 CopyBlob,
262 #[serde(rename = "PushSubscription/get")]
263 GetPushSubscription,
264 #[serde(rename = "PushSubscription/set")]
265 SetPushSubscription,
266 #[serde(rename = "Mailbox/get")]
267 GetMailbox,
268 #[serde(rename = "Mailbox/changes")]
269 ChangesMailbox,
270 #[serde(rename = "Mailbox/query")]
271 QueryMailbox,
272 #[serde(rename = "Mailbox/queryChanges")]
273 QueryChangesMailbox,
274 #[serde(rename = "Mailbox/set")]
275 SetMailbox,
276 #[serde(rename = "Thread/get")]
277 GetThread,
278 #[serde(rename = "Thread/changes")]
279 ChangesThread,
280 #[serde(rename = "Email/get")]
281 GetEmail,
282 #[serde(rename = "Email/changes")]
283 ChangesEmail,
284 #[serde(rename = "Email/query")]
285 QueryEmail,
286 #[serde(rename = "Email/queryChanges")]
287 QueryChangesEmail,
288 #[serde(rename = "Email/set")]
289 SetEmail,
290 #[serde(rename = "Email/copy")]
291 CopyEmail,
292 #[serde(rename = "Email/import")]
293 ImportEmail,
294 #[serde(rename = "Email/parse")]
295 ParseEmail,
296 #[serde(rename = "SearchSnippet/get")]
297 GetSearchSnippet,
298 #[serde(rename = "Identity/get")]
299 GetIdentity,
300 #[serde(rename = "Identity/changes")]
301 ChangesIdentity,
302 #[serde(rename = "Identity/set")]
303 SetIdentity,
304 #[serde(rename = "EmailSubmission/get")]
305 GetEmailSubmission,
306 #[serde(rename = "EmailSubmission/changes")]
307 ChangesEmailSubmission,
308 #[serde(rename = "EmailSubmission/query")]
309 QueryEmailSubmission,
310 #[serde(rename = "EmailSubmission/queryChanges")]
311 QueryChangesEmailSubmission,
312 #[serde(rename = "EmailSubmission/set")]
313 SetEmailSubmission,
314 #[serde(rename = "VacationResponse/get")]
315 GetVacationResponse,
316 #[serde(rename = "VacationResponse/set")]
317 SetVacationResponse,
318 #[serde(rename = "SieveScript/get")]
319 GetSieveScript,
320 #[serde(rename = "SieveScript/set")]
321 SetSieveScript,
322 #[serde(rename = "SieveScript/query")]
323 QuerySieveScript,
324 #[serde(rename = "SieveScript/validate")]
325 ValidateSieveScript,
326 #[serde(rename = "Principal/get")]
327 GetPrincipal,
328 #[serde(rename = "Principal/changes")]
329 ChangesPrincipal,
330 #[serde(rename = "Principal/query")]
331 QueryPrincipal,
332 #[serde(rename = "Principal/queryChanges")]
333 QueryChangesPrincipal,
334 #[serde(rename = "Principal/set")]
335 SetPrincipal,
336 #[serde(rename = "error")]
337 Error,
338}
339
340#[derive(Debug, Serialize, Deserialize, Eq, PartialEq, Hash, Clone)]
341pub enum DataType {
342 #[serde(rename = "Email")]
343 Email = 0,
344 #[serde(rename = "EmailDelivery")]
345 EmailDelivery = 1,
346 #[serde(rename = "EmailSubmission")]
347 EmailSubmission = 2,
348 #[serde(rename = "Mailbox")]
349 Mailbox = 3,
350 #[serde(rename = "Thread")]
351 Thread = 4,
352 #[serde(rename = "Identity")]
353 Identity = 5,
354 #[serde(rename = "Core")]
355 Core = 6,
356 #[serde(rename = "PushSubscription")]
357 PushSubscription = 7,
358 #[serde(rename = "SearchSnippet")]
359 SearchSnippet = 8,
360 #[serde(rename = "VacationResponse")]
361 VacationResponse = 9,
362 #[serde(rename = "MDN")]
363 Mdn = 10,
364 #[serde(rename = "Quota")]
365 Quota = 11,
366 #[serde(rename = "SieveScript")]
367 SieveScript = 12,
368 #[serde(rename = "Calendar")]
369 Calendar = 13,
370 #[serde(rename = "CalendarEvent")]
371 CalendarEvent = 14,
372 #[serde(rename = "CalendarEventNotification")]
373 CalendarEventNotification = 15,
374 #[serde(rename = "AddressBook")]
375 AddressBook = 16,
376 #[serde(rename = "ContactCard")]
377 ContactCard = 17,
378 #[serde(rename = "FileNode")]
379 FileNode = 18,
380 #[serde(rename = "Principal")]
381 Principal = 19,
382 #[serde(rename = "ShareNotification")]
383 ShareNotification = 20,
384 #[serde(rename = "ParticipantIdentity")]
385 ParticipantIdentity = 21,
386 #[serde(rename = "CalendarAlert")]
387 CalendarAlert = 22,
388}
389
390#[derive(Serialize, Deserialize, Debug)]
391#[serde(tag = "@type")]
392pub enum PushObject {
393 StateChange {
394 changed: AHashMap<String, AHashMap<DataType, String>>,
395 },
396 EmailPush {
397 #[serde(rename = "accountId")]
398 account_id: String,
399 email: serde_json::Value,
400 },
401 CalendarAlert(CalendarAlert),
402 Group {
403 entries: Vec<PushObject>,
404 },
405}
406
407#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
408pub struct CalendarAlert {
409 #[serde(rename = "accountId")]
410 pub account_id: String,
411 #[serde(rename = "calendarEventId")]
412 pub calendar_event_id: String,
413 pub uid: String,
414 #[serde(rename = "recurrenceId")]
415 pub recurrence_id: Option<String>,
416 #[serde(rename = "alertId")]
417 pub alert_id: String,
418}
419
420#[derive(Debug, Clone)]
421pub struct Get;
422#[derive(Debug, Clone)]
423pub struct Set;
424
425pub type Result<T> = std::result::Result<T, Error>;
426
427#[derive(Debug)]
428pub enum Error {
429 Transport(reqwest::Error),
430 Parse(serde_json::Error),
431 Internal(String),
432 Problem(Box<ProblemDetails>),
433 Server(String),
434 Method(MethodError),
435 Set(SetError<String>),
436 #[cfg(feature = "websockets")]
437 WebSocket(tokio_tungstenite::tungstenite::error::Error),
438}
439
440impl std::error::Error for Error {}
441
442impl From<reqwest::Error> for Error {
443 fn from(e: reqwest::Error) -> Self {
444 Error::Transport(e)
445 }
446}
447
448impl From<serde_json::Error> for Error {
449 fn from(e: serde_json::Error) -> Self {
450 Error::Parse(e)
451 }
452}
453
454impl From<MethodError> for Error {
455 fn from(e: MethodError) -> Self {
456 Error::Method(e)
457 }
458}
459
460impl From<ProblemDetails> for Error {
461 fn from(e: ProblemDetails) -> Self {
462 Error::Problem(Box::new(e))
463 }
464}
465
466impl From<SetError<String>> for Error {
467 fn from(e: SetError<String>) -> Self {
468 Error::Set(e)
469 }
470}
471
472impl From<&str> for Error {
473 fn from(s: &str) -> Self {
474 Error::Internal(s.to_string())
475 }
476}
477
478#[cfg(feature = "websockets")]
479impl From<tokio_tungstenite::tungstenite::error::Error> for Error {
480 fn from(e: tokio_tungstenite::tungstenite::error::Error) -> Self {
481 Error::WebSocket(e)
482 }
483}
484
485impl Display for Error {
486 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
487 match self {
488 Error::Transport(e) => write!(f, "Transport error: {}", e),
489 Error::Parse(e) => write!(f, "Parse error: {}", e),
490 Error::Internal(e) => write!(f, "Internal error: {}", e),
491 Error::Problem(e) => write!(f, "Request failed: {}", e),
492 Error::Server(e) => write!(f, "Server failed: {}", e),
493 Error::Method(e) => write!(f, "Request failed: {}", e),
494 Error::Set(e) => write!(f, "Set failed: {}", e),
495 #[cfg(feature = "websockets")]
496 Error::WebSocket(e) => write!(f, "WebSockets error: {}", e),
497 }
498 }
499}
500
501impl Display for DataType {
502 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
503 match self {
504 DataType::Mailbox => write!(f, "Mailbox"),
505 DataType::Thread => write!(f, "Thread"),
506 DataType::Email => write!(f, "Email"),
507 DataType::EmailDelivery => write!(f, "EmailDelivery"),
508 DataType::Identity => write!(f, "Identity"),
509 DataType::EmailSubmission => write!(f, "EmailSubmission"),
510 DataType::CalendarAlert => write!(f, "CalendarAlert"),
511 DataType::Core => write!(f, "Core"),
512 DataType::PushSubscription => write!(f, "PushSubscription"),
513 DataType::SearchSnippet => write!(f, "SearchSnippet"),
514 DataType::VacationResponse => write!(f, "VacationResponse"),
515 DataType::Mdn => write!(f, "MDN"),
516 DataType::Quota => write!(f, "Quota"),
517 DataType::SieveScript => write!(f, "SieveScript"),
518 DataType::Calendar => write!(f, "Calendar"),
519 DataType::CalendarEvent => write!(f, "CalendarEvent"),
520 DataType::CalendarEventNotification => write!(f, "CalendarEventNotification"),
521 DataType::AddressBook => write!(f, "AddressBook"),
522 DataType::ContactCard => write!(f, "ContactCard"),
523 DataType::FileNode => write!(f, "FileNode"),
524 DataType::Principal => write!(f, "Principal"),
525 DataType::ShareNotification => write!(f, "ShareNotification"),
526 DataType::ParticipantIdentity => write!(f, "ParticipantIdentity"),
527 }
528 }
529}