#![no_std]
#![cfg_attr(docsrs, feature(doc_cfg))]

//! # io-m2dir
//!
//! I/O-free m2dir coroutines: every filesystem exchange needed to
//! deliver, read, flag and remove messages in the
//! [m2dir](https://man.sr.ht/~bitfehler/m2dir/) mail storage format is a
//! resumable state machine emitting filesystem requests instead of
//! performing I/O itself, so the caller owns the syscalls and pumps the
//! coroutine (see the `client` feature for a ready-made std-blocking
//! pump).
//!
//! The crate ships two of the standard Pimalaya layers: the I/O-free
//! coroutines (no_std core, always present) and a std-blocking client
//! (`client` feature, default) backed by [`std::fs`]. There is no full
//! client layer: m2dir is local storage, so there is no socket to open.
//!
//! ## Layout
//!
//! The source tree groups coroutines by the object they act on, one
//! folder per object with a sibling module carrying the shared types:
//! [`m2dir`] (create, delete, list a mailbox directory, plus the
//! [`m2dir::M2dir`] handle), [`entry`] (store, get, list, delete a
//! message, plus [`entry::M2dirEntry`]) and [`flag`] (add, remove, set
//! flags, plus [`flag::M2dirFlags`]). Code reused across objects lives
//! at the crate root: the [`coroutine`] contract, the [`M2dirStore`]
//! root wrapper, the [`M2dirPath`] newtype and the private checksum
//! helpers. The std [`client`] spans every object.
//!
//! [`M2dirStore`]: store::M2dirStore
//! [`M2dirPath`]: path::M2dirPath
//!
//! ## The coroutine contract
//!
//! Every coroutine implements [`coroutine::M2dirCoroutine`], mirroring
//! the shape of `core::ops::Coroutine`: a `resume` step returns a
//! [`coroutine::M2dirCoroutineState`], either a yield or the terminal
//! result. io-m2dir is filesystem-flavoured, so every coroutine picks
//! the shared [`coroutine::M2dirYield`], which gathers every primitive
//! the crate emits: directory create, read and remove; file create,
//! read, exists and remove; path rename; and the process id and random
//! bytes needed to mint entry identifiers. The caller services each
//! yield and feeds the matching [`coroutine::M2dirArg`] back on the next
//! resume.
//!
//! ## The std client
//!
//! [`client::M2dirClient`] (`client` feature) wraps a filesystem root
//! pointing at an m2store and exposes one method per coroutine, running
//! each to completion against [`std::fs`]. It supplies the process id
//! and a xorshift64* random nonce the coroutines ask for, and adds a
//! thread-scoped parallel bulk read for reading many entries at once.
//!
//! ## Conventions
//!
//! The conventions every Pimalaya repository shares (the sans-I/O
//! coroutine approach, no_std, module and naming rules) are described in
//! the [Pimalaya ARCHITECTURE](https://github.com/pimalaya/.github/blob/master/ARCHITECTURE.md)
//! and [GUIDELINES](https://github.com/pimalaya/.github/blob/master/GUIDELINES.md).
//! Public types follow the M2dir-Target-Verb naming scheme
//! (`M2dirEntryStore`, `M2dirFlagAdd`) with Options, Output and Error
//! companions. Runnable snippets live in each coroutine module's
//! rustdoc, and the integration test exercises the full client surface.

#[macro_use]
extern crate alloc;
#[cfg(feature = "client")]
extern crate std;

mod checksum;

#[cfg(feature = "client")]
pub mod client;
pub mod coroutine;
pub mod entry;
pub mod flag;
pub mod m2dir;
pub mod path;
pub mod store;
