Skip to main content

io_jmap/
lib.rs

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