io-m2dir 0.2.0

M2dir client library for Rust
Documentation
# Design

## no_std core, std client

Everything except the client is a pure no_std core built on alloc alone; std lives behind the client feature only. The crate is meant to run cross-platform (Unix and Windows) and stay no_std-compatible like the other io-* crates' coroutines. There is no full-client layer: m2dir is local filesystem storage, so there is no socket to open and no TLS to negotiate.

## Hoisted I/O and non-determinism

Coroutines never touch the filesystem or the environment directly. Every side effect is a yield the caller services:

- Filesystem access is hoisted into M2dirYield variants (directory create, read, remove; file create, read, exists, remove; path rename) and answered through the matching M2dirArg.
- Existence checks are a separate WantsFileExists phase rather than an is_file call inside resume: list coroutines read directory names first, then probe candidates in one batch.
- Entry naming needs the process id and random bytes; both are hoisted through WantsPid and WantsRandom so the core stays deterministic and testable. The temporary-file counter stays a core AtomicU32.

## Paths and collections

A single M2dirPath newtype carries a fixed forward-slash separator regardless of host OS, so no PathBuf or Path appears in a coroutine signature; std::fs accepts forward-slash paths on both Unix and Windows, so the client needs no boundary conversion. All collections are BTreeSet and BTreeMap, never the hashed variants, so iteration order is deterministic and the flag sidecar is sorted for free.

## Module layout

Coroutines are grouped by the object they act on, one folder per object with a sibling module carrying the shared type: m2dir (M2dir), entry (M2dirEntry) and 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.

## Landed

- 2026-05-23: initial no_std design (M2dirPath newtype, hoisted I/O, BTreeSet-only, single-variant args kept). io-maildir was later aligned to the same shape.
- 2026-07-16: aligned with the Pimalaya documentation and naming guidelines. Retired the types and utils catch-all modules (types moved into their family module: entry, flag, m2dir; checksum helpers moved to a crate-root module; the date helper renamed from utils to date). Renamed ParseFilenameError to M2dirEntryParseError and LoadM2dirError to M2dirLoadError to carry the domain prefix. Made the marker constants crate-private. Rewrote the README as backtick-free public documentation, replaced the README-as-rustdoc lib.rs header with an architecture header, and removed the per-resume-loop trace logs.