io_jmap/lib.rs
1#![no_std]
2#![cfg_attr(docsrs, feature(doc_cfg))]
3
4//! # io-jmap
5//!
6//! I/O-free JMAP client coroutines built on io-http: every network
7//! exchange is a resumable state machine emitting read and write
8//! requests instead of performing I/O itself. The caller owns the
9//! socket and pumps the coroutine with the bytes it read, whatever the
10//! runtime (blocking, async, in-memory tests). The `client` feature
11//! ships a ready-made std-blocking pump for callers who just want a
12//! working client.
13//!
14//! ## Layout: one folder per RFC
15//!
16//! The source tree mirrors how the JMAP specification itself is
17//! split, one module per RFC. [`rfc8620`] implements the core
18//! protocol: the session, request and response objects, the generic
19//! `Foo/get`, `Foo/set`, `Foo/query`, `Foo/changes` and
20//! `Foo/queryChanges` coroutines every data type builds on, the blob
21//! upload and download coroutines, plus the two push channels
22//! (PushSubscription and the SSE-based Event Source). [`rfc8621`]
23//! covers JMAP for Mail: Mailbox, Thread, Email, Identity,
24//! EmailSubmission and VacationResponse, each folder wrapping the
25//! generic core coroutines with the mail capability and its own data
26//! types. [`rfc9610`] covers JMAP for Contacts: AddressBook and
27//! ContactCard, where the JSContact payload stays raw JSON, converting
28//! it being out of scope.
29//!
30//! Two modules span the RFC modules and therefore live at the crate
31//! root: [`coroutine`] defines the coroutine contract every state
32//! machine implements, and the optional [`client`] module (`client`
33//! feature) is the std-blocking pump: a light client wrapping any
34//! stream you opened yourself, or a full client opening the TCP/TLS
35//! connection itself when one of the TLS features is enabled.
36//!
37//! ## The coroutine contract
38//!
39//! Every coroutine implements [`coroutine::JmapCoroutine`]: a resume
40//! method taking the bytes read since the last step and returning
41//! either an intermediate yield or a terminal completion. Standard
42//! coroutines yield the shared read/write requests of
43//! [`coroutine::JmapYield`]; richer coroutines declare their own yield
44//! type, like the redirect-aware session and blob coroutines surfacing
45//! 3xx responses to the caller instead of following them, or the
46//! streaming Event Source coroutine yielding one push frame at a
47//! time. Completion carries a per-coroutine output or error; the
48//! [`jmap_try`] macro chains an inner coroutine step inside an outer
49//! resume, re-yielding and short-circuiting like the question mark
50//! operator.
51//!
52//! ## Conventions
53//!
54//! The crate is no_std with alloc; std only enters behind the `client`
55//! feature. Every public item carries the bare `Jmap` prefix, the
56//! protocol not being version-scoped. Logging follows the library
57//! rules: state changes at debug level, in-process steps and data
58//! dumps at trace level.
59
60extern crate alloc;
61#[cfg(feature = "client")]
62extern crate std;
63
64#[cfg(feature = "client")]
65pub mod client;
66pub mod coroutine;
67pub mod rfc8620;
68pub mod rfc8621;
69pub mod rfc9610;