v0.1.0
This commit is contained in:
62
examples/eventsource.rs
Normal file
62
examples/eventsource.rs
Normal file
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright Stalwart Labs Ltd. See the COPYING
|
||||
* file at the top-level directory of this distribution.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
* https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
* file at the top-level directory of this distribution.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
* https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
* <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
|
||||
* option. This file may not be copied, modified, or distributed
|
||||
* except according to those terms.
|
||||
*/
|
||||
|
||||
use futures_util::StreamExt;
|
||||
use jmap_client::{client::Client, TypeState};
|
||||
|
||||
async fn event_source() {
|
||||
// Connect to the JMAP server using Basic authentication
|
||||
let client = Client::new()
|
||||
.credentials(("john@example.org", "secret"))
|
||||
.connect("https://jmap.example.org")
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
// Open EventSource connection
|
||||
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
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let _c = event_source();
|
||||
}
|
||||
69
examples/mailboxes.rs
Normal file
69
examples/mailboxes.rs
Normal file
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright Stalwart Labs Ltd. See the COPYING
|
||||
* file at the top-level directory of this distribution.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
* https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
* file at the top-level directory of this distribution.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
* https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
* <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
|
||||
* option. This file may not be copied, modified, or distributed
|
||||
* except according to those terms.
|
||||
*/
|
||||
|
||||
use jmap_client::{
|
||||
client::Client,
|
||||
mailbox::{query::Filter, Role},
|
||||
};
|
||||
|
||||
async fn mailboxes() {
|
||||
// Connect to the JMAP server using Basic authentication
|
||||
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();
|
||||
|
||||
// Rename a mailbox
|
||||
client
|
||||
.mailbox_rename(&mailbox_id, "My Renamed Mailbox")
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
// Query mailboxes to obtain Inbox's id
|
||||
let inbox_id = client
|
||||
.mailbox_query(Filter::role(Role::Inbox).into(), None::<Vec<_>>)
|
||||
.await
|
||||
.unwrap()
|
||||
.take_ids()
|
||||
.pop()
|
||||
.unwrap();
|
||||
|
||||
// Print Inbox's details
|
||||
println!(
|
||||
"{:?}",
|
||||
client.mailbox_get(&inbox_id, None::<Vec<_>>).await.unwrap()
|
||||
);
|
||||
|
||||
// Move the newly created mailbox under Inbox
|
||||
client
|
||||
.mailbox_move(&mailbox_id, inbox_id.into())
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
// Delete the mailbox including any messages
|
||||
client.mailbox_destroy(&mailbox_id, true).await.unwrap();
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let _c = mailboxes();
|
||||
}
|
||||
120
examples/messages.rs
Normal file
120
examples/messages.rs
Normal file
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
* Copyright Stalwart Labs Ltd. See the COPYING
|
||||
* file at the top-level directory of this distribution.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
* https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
* file at the top-level directory of this distribution.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
* https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
* <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
|
||||
* option. This file may not be copied, modified, or distributed
|
||||
* except according to those terms.
|
||||
*/
|
||||
|
||||
use jmap_client::{
|
||||
client::Client,
|
||||
core::query::Filter,
|
||||
email::{self, Property},
|
||||
mailbox::{self, Role},
|
||||
};
|
||||
|
||||
const TEST_MESSAGE: &[u8; 90] = br#"From: john@example.org
|
||||
To: jane@example.org
|
||||
Subject: Testing JMAP client
|
||||
|
||||
This is a test.
|
||||
"#;
|
||||
|
||||
async fn messages() {
|
||||
// Connect to the JMAP server using Basic authentication
|
||||
let client = Client::new()
|
||||
.credentials(("john@example.org", "secret"))
|
||||
.connect("https://jmap.example.org")
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
// Query mailboxes to obtain Inbox and Trash folder id
|
||||
let inbox_id = client
|
||||
.mailbox_query(
|
||||
mailbox::query::Filter::role(Role::Inbox).into(),
|
||||
None::<Vec<_>>,
|
||||
)
|
||||
.await
|
||||
.unwrap()
|
||||
.take_ids()
|
||||
.pop()
|
||||
.unwrap();
|
||||
let trash_id = client
|
||||
.mailbox_query(
|
||||
mailbox::query::Filter::role(Role::Trash).into(),
|
||||
None::<Vec<_>>,
|
||||
)
|
||||
.await
|
||||
.unwrap()
|
||||
.take_ids()
|
||||
.pop()
|
||||
.unwrap();
|
||||
|
||||
// Import message into inbox
|
||||
client
|
||||
.email_import(TEST_MESSAGE.to_vec(), [&inbox_id], ["$draft"].into(), None)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
// Query mailbox
|
||||
let email_id = client
|
||||
.email_query(
|
||||
Filter::and([
|
||||
email::query::Filter::subject("test"),
|
||||
email::query::Filter::in_mailbox(&inbox_id),
|
||||
email::query::Filter::has_keyword("$draft"),
|
||||
])
|
||||
.into(),
|
||||
[email::query::Comparator::from()].into(),
|
||||
)
|
||||
.await
|
||||
.unwrap()
|
||||
.take_ids()
|
||||
.pop()
|
||||
.unwrap();
|
||||
|
||||
// Fetch message
|
||||
let email = client
|
||||
.email_get(
|
||||
&email_id,
|
||||
[Property::Subject, Property::Preview, Property::Keywords].into(),
|
||||
)
|
||||
.await
|
||||
.unwrap()
|
||||
.unwrap();
|
||||
assert_eq!(email.preview().unwrap(), "This is a test.");
|
||||
assert_eq!(email.subject().unwrap(), "Testing JMAP client");
|
||||
assert_eq!(email.keywords(), ["$draft"]);
|
||||
|
||||
// Remove the $draft keyword
|
||||
client
|
||||
.email_set_keyword(&email_id, "$draft", false)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
// Replace all keywords
|
||||
client
|
||||
.email_set_keywords(&email_id, ["$seen", "$important"])
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
// Move the message to the Trash folder
|
||||
client
|
||||
.email_set_mailboxes(&email_id, [&trash_id])
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
// Destroy the e-mail
|
||||
client.email_destroy(&email_id).await.unwrap();
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let _c = messages();
|
||||
}
|
||||
101
examples/result_reference.rs
Normal file
101
examples/result_reference.rs
Normal file
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* Copyright Stalwart Labs Ltd. See the COPYING
|
||||
* file at the top-level directory of this distribution.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
* https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
* file at the top-level directory of this distribution.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
* https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
* <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
|
||||
* option. This file may not be copied, modified, or distributed
|
||||
* except according to those terms.
|
||||
*/
|
||||
|
||||
use jmap_client::{client::Client, core::query, email, mailbox};
|
||||
|
||||
async fn result_reference() {
|
||||
// Connect to the JMAP server using Basic authentication
|
||||
let client = Client::new()
|
||||
.credentials(("john@example.org", "secret"))
|
||||
.connect("https://jmap.example.org")
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
// Delete e-mails matching a filter
|
||||
let mut request = client.build();
|
||||
let result_ref = request
|
||||
.query_email()
|
||||
.filter(query::Filter::and([
|
||||
email::query::Filter::has_keyword("$draft"),
|
||||
email::query::Filter::from("bill"),
|
||||
]))
|
||||
.result_reference();
|
||||
request.set_email().destroy_ref(result_ref);
|
||||
let _destroyed_ids = request
|
||||
.send()
|
||||
.await
|
||||
.unwrap()
|
||||
.unwrap_method_responses()
|
||||
.pop()
|
||||
.unwrap()
|
||||
.unwrap_set_email()
|
||||
.unwrap()
|
||||
.take_destroyed_ids();
|
||||
|
||||
// Fetch mailboxes matching a filter
|
||||
let mut request = client.build();
|
||||
let query_result = request
|
||||
.query_mailbox()
|
||||
.filter(query::Filter::and([
|
||||
mailbox::query::Filter::has_any_role(false),
|
||||
mailbox::query::Filter::is_subscribed(true),
|
||||
]))
|
||||
.result_reference();
|
||||
request.get_mailbox().ids_ref(query_result).properties([
|
||||
mailbox::Property::Id,
|
||||
mailbox::Property::Name,
|
||||
mailbox::Property::ParentId,
|
||||
mailbox::Property::TotalEmails,
|
||||
mailbox::Property::UnreadEmails,
|
||||
]);
|
||||
let _mailboxes = request
|
||||
.send()
|
||||
.await
|
||||
.unwrap()
|
||||
.unwrap_method_responses()
|
||||
.pop()
|
||||
.unwrap()
|
||||
.unwrap_get_mailbox()
|
||||
.unwrap()
|
||||
.take_list();
|
||||
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let _c = result_reference();
|
||||
}
|
||||
86
examples/websocket.rs
Normal file
86
examples/websocket.rs
Normal file
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright Stalwart Labs Ltd. See the COPYING
|
||||
* file at the top-level directory of this distribution.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
* https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
* file at the top-level directory of this distribution.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
* https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
* <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
|
||||
* option. This file may not be copied, modified, or distributed
|
||||
* except according to those terms.
|
||||
*/
|
||||
|
||||
use futures_util::StreamExt;
|
||||
use jmap_client::{client::Client, client_ws::WebSocketMessage, core::set::SetObject};
|
||||
use tokio::sync::mpsc;
|
||||
|
||||
// Make sure the "websockets" feature is enabled!
|
||||
async fn websocket() {
|
||||
// Connect to the JMAP server using Basic authentication
|
||||
let client = Client::new()
|
||||
.credentials(("john@example.org", "secret"))
|
||||
.connect("https://jmap.example.org")
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
// Connect to the WebSocket endpoint
|
||||
let mut ws_stream = client.connect_ws().await.unwrap();
|
||||
|
||||
// Read WS messages on a separate thread
|
||||
let (stream_tx, mut stream_rx) = mpsc::channel::<WebSocketMessage>(100);
|
||||
tokio::spawn(async move {
|
||||
while let Some(change) = ws_stream.next().await {
|
||||
stream_tx.send(change.unwrap()).await.unwrap();
|
||||
}
|
||||
});
|
||||
|
||||
// Create a mailbox over WS
|
||||
let mut request = client.build();
|
||||
let create_id = request
|
||||
.set_mailbox()
|
||||
.create()
|
||||
.name("WebSocket Test")
|
||||
.create_id()
|
||||
.unwrap();
|
||||
let request_id = request.send_ws().await.unwrap();
|
||||
|
||||
// Read response from WS stream
|
||||
let mailbox_id = if let Some(WebSocketMessage::Response(mut response)) = stream_rx.recv().await
|
||||
{
|
||||
assert_eq!(request_id, response.request_id().unwrap());
|
||||
response
|
||||
.pop_method_response()
|
||||
.unwrap()
|
||||
.unwrap_set_mailbox()
|
||||
.unwrap()
|
||||
.created(&create_id)
|
||||
.unwrap()
|
||||
.take_id()
|
||||
} else {
|
||||
unreachable!()
|
||||
};
|
||||
|
||||
// Enable push notifications over WS
|
||||
client
|
||||
.enable_push_ws(None::<Vec<_>>, None::<&str>)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
// Make changes over standard HTTP and expect a push notification via WS
|
||||
client
|
||||
.mailbox_update_sort_order(&mailbox_id, 1)
|
||||
.await
|
||||
.unwrap();
|
||||
if let Some(WebSocketMessage::StateChange(changes)) = stream_rx.recv().await {
|
||||
println!("Received changes: {:?}", changes);
|
||||
} else {
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let _c = websocket();
|
||||
}
|
||||
Reference in New Issue
Block a user