@@ -9,37 +9,48 @@ no longer applies rather than leaving it to rot.
99
1010## Project Structure
1111
12- This is a Cargo ** workspace** : the ` tinymemory ` facade at the root, the
13- ` tinymemory-api ` contract in ` api/ ` , and one engine adapter per directory under
14- ` adapters/ ` . Engines themselves are submodules under ` vendor/ ` , excluded from
15- the workspace.
16-
17- See [ ` README.md ` ] ( README.md ) for the layout and the rules that govern it — in
18- particular, why policy stays in the host and why adapters name their engines by
19- version requirement rather than by path.
12+ This is a Cargo ** workspace** with a virtual root: there is no root package,
13+ and every crate lives in its own directory under ` crates/ ` , named for the
14+ package it holds. ` members ` is the glob ` crates/* ` , so a new crate joins the
15+ workspace by existing. ` crates/tinymemory ` is the facade a host depends on;
16+ ` crates/tinymemory-api ` is the contract; the rest are the subsystems and the
17+ engine adapters, each reachable from the facade by a feature named after it.
18+ Engines themselves are submodules under ` vendor/ ` , excluded from the workspace.
19+
20+ See [ ` README.md ` ] ( README.md ) for the full layout, the feature table, and the
21+ rules that govern them — in particular, why policy stays in the host and why
22+ adapters name their engines by version requirement rather than by path.
2023
2124``` text
22- src/
23- ├── lib.rs # crate docs + the entire public re-export surface
24- ├── error/mod.rs # crate-wide `Error` and `Result<T>`
25- └── <feature>/ # one directory per feature area
26- ├── mod.rs # module docs, wiring, smallest useful public API
27- ├── types.rs # substantial type definitions
28- └── test.rs # module-local unit tests
29- tests/ # integration tests against the public API only
30- examples/ # runnable, compiled-in-CI usage examples
25+ crates/<package>/
26+ ├── Cargo.toml # one package; `[lints]` opted into per crate
27+ ├── README.md # required of complex crates: design, surface, caveats
28+ └── src/
29+ ├── lib.rs # crate docs + the entire public re-export surface
30+ ├── error/mod.rs # crate-wide `Error` and `Result<T>`
31+ └── <feature>/ # one directory per feature area
32+ ├── mod.rs # module docs, wiring, smallest useful public API
33+ ├── types.rs # substantial type definitions
34+ └── test.rs # module-local unit tests
35+ crates/<package>/tests/ # integration tests against the public API only
36+ crates/<package>/examples/ # runnable, compiled-in-CI usage examples
3137vendor/tinybus/ # pinned TinyBus source; optional until wired by a project
3238docs/
3339├── specs/ # behavior and architecture specifications
3440├── plans/ # test-first implementation plans
3541└── adr/ # immutable architecture decision records
3642```
3743
38- Each feature area belongs in a focused module directory under ` src/ ` . A module
39- root explains the module, wires its pieces together, and exposes the smallest
40- useful API. Move substantial type definitions into ` types.rs ` and put
41- module-local unit tests in a dedicated ` test.rs ` , wired from the bottom of the
42- module root with:
44+ A new crate goes in ` crates/<package>/ ` , and a package that is not an adapter
45+ or a subsystem of the memory layer probably does not belong here at all. Reach
46+ it from the facade by adding an optional dependency and a feature of the same
47+ name, so a host keeps taking one dependency and stating what it wants.
48+
49+ Each feature area belongs in a focused module directory under the crate's
50+ ` src/ ` . A module root explains the module, wires its pieces together, and
51+ exposes the smallest useful API. Move substantial type definitions into
52+ ` types.rs ` and put module-local unit tests in a dedicated ` test.rs ` , wired from
53+ the bottom of the module root with:
4354
4455``` rust
4556#[cfg(test)]
@@ -51,9 +62,10 @@ let a general-purpose `utils.rs` or `helpers.rs` grow — those are a symptom of
5162missing module. Prefer many small modules that each do one thing well over few
5263broad ones.
5364
54- Keep public exports centralized in ` src/lib.rs ` so downstream users have one
55- predictable surface. Put shared error variants in ` src/error/mod.rs ` and return
56- the crate-wide ` Result<T> ` from fallible public APIs.
65+ Keep public exports centralized in each crate's ` src/lib.rs ` so downstream
66+ users have one predictable surface. Put shared error variants in
67+ ` src/error/mod.rs ` and return the crate-wide ` Result<T> ` from fallible public
68+ APIs.
5769
5870## Build And Test
5971
@@ -71,7 +83,9 @@ Supporting commands:
7183
7284- ` cargo fmt --all ` — format before committing.
7385- ` cargo test <filter> ` — run a focused subset while iterating.
74- - ` cargo run --example basic ` — run the bundled example.
86+ - ` cargo run -p tinymemory --example basic ` — run the bundled example. The
87+ ` -p ` is required: the workspace root is virtual, so cargo cannot infer which
88+ package an example belongs to.
7589- ` cargo doc --no-deps --all-features ` — build the rustdoc CI also builds with
7690 ` RUSTDOCFLAGS="-D warnings" ` .
7791- ` cargo test --doc ` — run doctests alone when editing documentation examples.
@@ -92,14 +106,16 @@ Use standard `rustfmt` output and Rust 2024 idioms. Do not hand-format around
92106- Prefer small, typed APIs over stringly-typed ones. Accept ` &str ` and generic
93107 ` impl Into<String> ` at boundaries; return owned, concrete types.
94108- Keep the public surface minimal: default to private, and export deliberately
95- from ` src/lib.rs ` .
96- - ` unsafe ` is forbidden crate-wide by the lint configuration in ` Cargo.toml ` .
97- If a project genuinely needs it, relax the lint in its own commit and document
98- every invariant with a ` // SAFETY: ` comment.
109+ from the crate's ` src/lib.rs ` .
110+ - ` unsafe ` is forbidden crate-wide by the ` [lints] ` table in each crate's own
111+ ` Cargo.toml ` — the root is virtual and carries no lint configuration. If a
112+ crate genuinely needs it, relax the lint in its own commit and document every
113+ invariant with a ` // SAFETY: ` comment.
99114
100115### Errors
101116
102- - One crate-wide ` Error ` enum in ` src/error/mod.rs ` , built with ` thiserror ` .
117+ - One crate-wide ` Error ` enum in the crate's ` src/error/mod.rs ` , built with
118+ ` thiserror ` .
103119- Fallible public functions return ` Result<T> ` , the crate alias.
104120- Add a specific variant instead of stuffing context into a string; error
105121 messages are lowercase, without trailing punctuation.
@@ -143,10 +159,10 @@ on every generated crate.
143159
144160## Testing
145161
146- - Module-local unit tests live in ` src/<feature>/test.rs ` and may touch private
147- items.
148- - Integration tests live in ` tests/ ` and exercise only the public API — they are
149- the regression suite for the crate's contract.
162+ - Module-local unit tests live in ` crates/<package>/ src/<feature>/test.rs` and
163+ may touch private items.
164+ - Integration tests live in ` crates/<package>/ tests/` and exercise only the
165+ public API — they are the regression suite for the crate's contract.
150166- Use descriptive, behavioral test names: ` rejects_an_empty_name ` , not
151167 ` test_greet_2 ` .
152168- Cover the failure paths, not just the happy path. Every new error variant
@@ -171,8 +187,8 @@ Write documentation for the reader who has never seen the code.
171187 treats as an error.
172188- Start every ` mod.rs ` and ` test.rs ` with a concise module-level ` //! `
173189 description.
174- - ` src/lib.rs ` carries the crate-level overview: what the crate does, the
175- primary entry points, and a short runnable example.
190+ - Each crate's ` src/lib.rs ` carries its crate-level overview: what the crate
191+ does, its primary entry points, and a short runnable example.
176192- Prefer concrete examples over vague description. Doc examples are compiled and
177193 run by ` cargo test ` , so they cannot drift.
178194- Complex modules must include a module-level ` README.md ` covering their design,
@@ -221,13 +237,14 @@ explicitly declined with a reason.
221237Releases run from ` .github/workflows/release.yml ` via a manual
222238` workflow_dispatch ` with a ` patch ` / ` minor ` / ` major ` bump. The workflow
223239re-runs the full validation suite, computes the next version, updates
224- ` Cargo.toml ` and ` Cargo.lock ` , commits and tags ` vX.Y.Z ` , packages, pushes, and
225- publishes to crates.io using the ` CARGO_REGISTRY_TOKEN ` secret.
240+ ` crates/tinymemory/Cargo.toml ` and ` Cargo.lock ` , commits and tags ` vX.Y.Z ` ,
241+ packages, pushes, and publishes to crates.io using the ` CARGO_REGISTRY_TOKEN `
242+ secret.
226243
227244Consequently:
228245
229- - Do not hand-edit the ` version ` field in ` Cargo.toml ` ; the release workflow
230- owns it.
246+ - Do not hand-edit the ` version ` field in ` crates/tinymemory/ Cargo.toml` ; the
247+ release workflow owns it.
231248- Follow semantic versioning. Any change to the public surface that is not
232249 purely additive is a breaking change and needs a major bump (pre-1.0: a minor
233250 bump).
0 commit comments