This commit is contained in:
Mauro D
2022-09-09 09:49:32 +00:00
parent 5e9c4f825e
commit 2e70d350ed
8 changed files with 786 additions and 9 deletions

View File

@@ -9,13 +9,177 @@
* except according to those terms.
*/
use crate::core::error::MethodError;
use crate::core::error::ProblemDetails;
use crate::core::set::SetError;
use ahash::AHashMap;
use serde::{Deserialize, Serialize};
use std::fmt::Display;
//! # jmap-client
//!
//! [![crates.io](https://img.shields.io/crates/v/jmap-client)](https://crates.io/crates/jmap-client)
//! [![build](https://github.com/stalwartlabs/jmap-client/actions/workflows/rust.yml/badge.svg)](https://github.com/stalwartlabs/jmap-client/actions/workflows/rust.yml)
//! [![docs.rs](https://img.shields.io/docsrs/jmap-client)](https://docs.rs/jmap-client)
//! [![crates.io](https://img.shields.io/crates/l/jmap-client)](http://www.apache.org/licenses/LICENSE-2.0)
//!
//! _jmap-client_ is a **JSON Meta Application Protocol (JMAP) library** written in Rust. The library is a full implementation of the JMAP RFCs including:
//!
//! - JMAP Core ([RFC 8620](https://datatracker.ietf.org/doc/html/rfc8620))
//! - JMAP for Mail ([RFC 8621](https://datatracker.ietf.org/doc/html/rfc8621))
//! - JMAP over WebSocket ([RFC 8887](https://datatracker.ietf.org/doc/html/rfc8887)).
//!
//! Features:
//!
//! - Async and blocking support (use the cargo feature ``blocking`` to enable blocking).
//! - WebSocket async streams (use the cargo feature ``websockets`` to enable JMAP over WebSocket).
//! - EventSource async streams.
//! - Helper functions to reduce boilerplate code and quickly build JMAP requests.
//! - Fast parsing and encoding of JMAP requests.
//!
//! ## Usage Example
//!
//! ```rust
//! // Connect to the JMAP server using Basic authentication.
//! // (just for demonstration purposes, Bearer tokens should be used instead)
//! let client = Client::new()
//! .credentials(("john@example.org", "secret"))
//! .connect("https://jmap.example.org")
//! .await
//! .unwrap();
//!
//! // Create a mailbox.
//! let mailbox_id = client
//! .mailbox_create("My Mailbox", None::<String>, Role::None)
//! .await
//! .unwrap()
//! .take_id();
//!
//! // Import a message into the mailbox.
//! client
//! .email_import(
//! b"From: john@example.org\nSubject: test\n\n test".to_vec(),
//! [&mailbox_id],
//! ["$draft"].into(),
//! None,
//! )
//! .await
//! .unwrap();
//!
//! // Obtain all e-mail ids matching a filter.
//! let email_id = client
//! .email_query(
//! Filter::and([
//! email::query::Filter::subject("test"),
//! email::query::Filter::in_mailbox(&mailbox_id),
//! email::query::Filter::has_keyword("$draft"),
//! ])
//! .into(),
//! [email::query::Comparator::from()].into(),
//! )
//! .await
//! .unwrap()
//! .take_ids()
//! .pop()
//! .unwrap();
//!
//! // Fetch an e-mail message.
//! let email = client
//! .email_get(
//! &email_id,
//! [Property::Subject, Property::Preview, Property::Keywords].into(),
//! )
//! .await
//! .unwrap()
//! .unwrap();
//! assert_eq!(email.preview().unwrap(), "test");
//! assert_eq!(email.subject().unwrap(), "test");
//! assert_eq!(email.keywords(), ["$draft"]);
//!
//! // Fetch only the updated properties of all mailboxes that changed
//! // since a state.
//! let mut request = client.build();
//! let changes_request = request.changes_mailbox("n").max_changes(0);
//! let properties_ref = changes_request.updated_properties_reference();
//! let updated_ref = changes_request.updated_reference();
//! request
//! .get_mailbox()
//! .ids_ref(updated_ref)
//! .properties_ref(properties_ref);
//! for mailbox in request
//! .send()
//! .await
//! .unwrap()
//! .unwrap_method_responses()
//! .pop()
//! .unwrap()
//! .unwrap_get_mailbox()
//! .unwrap()
//! .take_list()
//! {
//! println!("Changed mailbox: {:#?}", mailbox);
//! }
//!
//! // Delete the mailbox including any messages
//! client.mailbox_destroy(&mailbox_id, true).await.unwrap();
//!
//! // Open an EventSource connection with the JMAP server.
//! let mut stream = client
//! .event_source(
//! [
//! TypeState::Email,
//! TypeState::EmailDelivery,
//! TypeState::Mailbox,
//! TypeState::EmailSubmission,
//! TypeState::Identity,
//! ]
//! .into(),
//! false,
//! 60.into(),
//! None,
//! )
//! .await
//! .unwrap();
//!
//! // Consume events received over EventSource.
//! while let Some(event) = stream.next().await {
//! let changes = event.unwrap();
//! println!("-> Change id: {:?}", changes.id());
//! for account_id in changes.changed_accounts() {
//! println!(" Account {} has changes:", account_id);
//! if let Some(account_changes) = changes.changes(account_id) {
//! for (type_state, state_id) in account_changes {
//! println!(" Type {:?} has a new state {}.", type_state, state_id);
//! }
//! }
//! }
//! }
//! ```
//!
//! More examples available under the [examples](examples) directory.
//!
//! ## Testing
//!
//! To run the testsuite:
//!
//! ```bash
//! $ cargo test --all-features
//! ```
//!
//! ## Conformed RFCs
//!
//! - [RFC 8620 - The JSON Meta Application Protocol (JMAP)](https://datatracker.ietf.org/doc/html/rfc8620)
//! - [RFC 8621 - The JSON Meta Application Protocol (JMAP) for Mail](https://datatracker.ietf.org/doc/html/rfc8621)
//! - [RFC 8887 - A JSON Meta Application Protocol (JMAP) Subprotocol for WebSocket](https://datatracker.ietf.org/doc/html/rfc8887)
//!
//! ## License
//!
//! Licensed under either of
//!
//! * Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
//! * MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)
//!
//! at your option.
//!
//! ## Copyright
//!
//! Copyright (C) 2022, Stalwart Labs Ltd.
//!
#[forbid(unsafe_code)]
pub mod blob;
pub mod client;
pub mod core;
@@ -30,6 +194,13 @@ pub mod push_subscription;
pub mod thread;
pub mod vacation_response;
use crate::core::error::MethodError;
use crate::core::error::ProblemDetails;
use crate::core::set::SetError;
use ahash::AHashMap;
use serde::{Deserialize, Serialize};
use std::fmt::Display;
#[cfg(feature = "websockets")]
pub mod client_ws;