{"id":20747121,"url":"https://github.com/stalwartlabs/jmap-client","last_synced_at":"2025-04-05T18:05:51.133Z","repository":{"id":58926557,"uuid":"489878150","full_name":"stalwartlabs/jmap-client","owner":"stalwartlabs","description":"JMAP client library for Rust","archived":false,"fork":false,"pushed_at":"2023-12-29T09:35:18.000Z","size":263,"stargazers_count":78,"open_issues_count":5,"forks_count":8,"subscribers_count":5,"default_branch":"main","last_synced_at":"2025-03-29T17:02:42.611Z","etag":null,"topics":["email","jmap","jmap-client","mail","rust"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/stalwartlabs.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE-APACHE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"open_collective":"stalwart","github":"stalwartlabs","ko_fi":null,"patreon":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"otechie":null,"lfx_crowdfunding":null,"custom":null}},"created_at":"2022-05-08T07:41:46.000Z","updated_at":"2025-03-25T01:46:35.000Z","dependencies_parsed_at":"2022-09-22T00:42:37.016Z","dependency_job_id":"5d6254da-ddec-49c2-8948-9d369e11a618","html_url":"https://github.com/stalwartlabs/jmap-client","commit_stats":{"total_commits":64,"total_committers":3,"mean_commits":"21.333333333333332","dds":0.0625,"last_synced_commit":"be63232d4cc70fbff2a8b9ee736ba40159cd8f0f"},"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stalwartlabs%2Fjmap-client","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stalwartlabs%2Fjmap-client/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stalwartlabs%2Fjmap-client/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stalwartlabs%2Fjmap-client/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/stalwartlabs","download_url":"https://codeload.github.com/stalwartlabs/jmap-client/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247378140,"owners_count":20929296,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["email","jmap","jmap-client","mail","rust"],"created_at":"2024-11-17T08:11:33.870Z","updated_at":"2025-04-05T18:05:51.107Z","avatar_url":"https://github.com/stalwartlabs.png","language":"Rust","funding_links":["https://opencollective.com/stalwart","https://github.com/sponsors/stalwartlabs"],"categories":[],"sub_categories":[],"readme":"# jmap-client\n\n[![crates.io](https://img.shields.io/crates/v/jmap-client)](https://crates.io/crates/jmap-client)\n[![build](https://github.com/stalwartlabs/jmap-client/actions/workflows/rust.yml/badge.svg)](https://github.com/stalwartlabs/jmap-client/actions/workflows/rust.yml)\n[![docs.rs](https://img.shields.io/docsrs/jmap-client)](https://docs.rs/jmap-client)\n[![crates.io](https://img.shields.io/crates/l/jmap-client)](http://www.apache.org/licenses/LICENSE-2.0)\n\n_jmap-client_ is a **JSON Meta Application Protocol (JMAP) library** written in Rust. The library is a full implementation of the JMAP RFCs including:\n\n- JMAP Core ([RFC 8620](https://datatracker.ietf.org/doc/html/rfc8620))\n- JMAP for Mail ([RFC 8621](https://datatracker.ietf.org/doc/html/rfc8621)) \n- JMAP over WebSocket ([RFC 8887](https://datatracker.ietf.org/doc/html/rfc8887)).\n- JMAP for Sieve Scripts ([DRAFT-SIEVE-14](https://www.ietf.org/archive/id/draft-ietf-jmap-sieve-14.html)).\n\nFeatures:\n\n- Async and blocking support (use the cargo feature ``blocking`` to enable blocking).\n- WebSocket async streams (use the cargo feature ``websockets`` to enable JMAP over WebSocket).\n- EventSource async streams.\n- Helper functions to reduce boilerplate code and quickly build JMAP requests.\n- Fast parsing and encoding of JMAP requests.\n\n## Usage Example\n\n```rust\n// Connect to the JMAP server using Basic authentication.\n// (just for demonstration purposes, Bearer tokens should be used instead)\nlet client = Client::new()\n    .credentials((\"john@example.org\", \"secret\"))\n    .connect(\"https://jmap.example.org\")\n    .await\n    .unwrap();\n\n// Create a mailbox.\nlet mailbox_id = client\n    .mailbox_create(\"My Mailbox\", None::\u003cString\u003e, Role::None)\n    .await\n    .unwrap()\n    .take_id();\n\n// Import a message into the mailbox.\nclient\n    .email_import(\n        b\"From: john@example.org\\nSubject: test\\n\\n test\".to_vec(),\n        [\u0026mailbox_id],\n        [\"$draft\"].into(),\n        None,\n    )\n    .await\n    .unwrap();\n\n// Obtain all e-mail ids matching a filter.\nlet email_id = client\n    .email_query(\n        Filter::and([\n            email::query::Filter::subject(\"test\"),\n            email::query::Filter::in_mailbox(\u0026mailbox_id),\n            email::query::Filter::has_keyword(\"$draft\"),\n        ])\n        .into(),\n        [email::query::Comparator::from()].into(),\n    )\n    .await\n    .unwrap()\n    .take_ids()\n    .pop()\n    .unwrap();\n\n// Fetch an e-mail message.\nlet email = client\n    .email_get(\n        \u0026email_id,\n        [Property::Subject, Property::Preview, Property::Keywords].into(),\n    )\n    .await\n    .unwrap()\n    .unwrap();\nassert_eq!(email.preview().unwrap(), \"test\");\nassert_eq!(email.subject().unwrap(), \"test\");\nassert_eq!(email.keywords(), [\"$draft\"]);\n\n// Fetch only the updated properties of all mailboxes that changed\n// since a state.\nlet mut request = client.build();\nlet changes_request = request.changes_mailbox(\"n\").max_changes(0);\nlet properties_ref = changes_request.updated_properties_reference();\nlet updated_ref = changes_request.updated_reference();\nrequest\n    .get_mailbox()\n    .ids_ref(updated_ref)\n    .properties_ref(properties_ref);\nfor mailbox in request\n    .send()\n    .await\n    .unwrap()\n    .unwrap_method_responses()\n    .pop()\n    .unwrap()\n    .unwrap_get_mailbox()\n    .unwrap()\n    .take_list()\n{\n    println!(\"Changed mailbox: {:#?}\", mailbox);\n}\n\n// Delete the mailbox including any messages\nclient.mailbox_destroy(\u0026mailbox_id, true).await.unwrap();\n\n// Open an EventSource connection with the JMAP server.\nlet mut stream = client\n    .event_source(\n        [\n            TypeState::Email,\n            TypeState::EmailDelivery,\n            TypeState::Mailbox,\n            TypeState::EmailSubmission,\n            TypeState::Identity,\n        ]\n        .into(),\n        false,\n        60.into(),\n        None,\n    )\n    .await\n    .unwrap();\n\n// Consume events received over EventSource.\nwhile let Some(event) = stream.next().await {\n    let changes = event.unwrap();\n    println!(\"-\u003e Change id: {:?}\", changes.id());\n    for account_id in changes.changed_accounts() {\n        println!(\" Account {} has changes:\", account_id);\n        if let Some(account_changes) = changes.changes(account_id) {\n            for (type_state, state_id) in account_changes {\n                println!(\"   Type {:?} has a new state {}.\", type_state, state_id);\n            }\n        }\n    }\n}\n```\n\nMore examples available under the [examples](examples) directory. \n\n## Testing\n\nTo run the testsuite:\n\n```bash\n $ cargo test --all-features\n```\n\n## Conformed RFCs\n\n- [RFC 8620 - The JSON Meta Application Protocol (JMAP)](https://datatracker.ietf.org/doc/html/rfc8620)\n- [RFC 8621 - The JSON Meta Application Protocol (JMAP) for Mail](https://datatracker.ietf.org/doc/html/rfc8621)\n- [RFC 8887 - A JSON Meta Application Protocol (JMAP) Subprotocol for WebSocket](https://datatracker.ietf.org/doc/html/rfc8887)\n\n## License\n\nLicensed under either of\n\n * Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)\n * MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)\n\nat your option.\n\n## Copyright\n\nCopyright (C) 2022, Stalwart Labs Ltd.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstalwartlabs%2Fjmap-client","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fstalwartlabs%2Fjmap-client","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstalwartlabs%2Fjmap-client/lists"}