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