Skip to content

Commit fa343cb

Browse files
committed
update original
1 parent 689b4e2 commit fa343cb

18 files changed

Lines changed: 205 additions & 56 deletions

File tree

rust-cookbook/CLAUDE.md

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
# CLAUDE.md
2+
3+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4+
5+
## Project Overview
6+
7+
This is the **Rust Cookbook** — an mdBook-based collection of practical Rust examples using ecosystem crates. Examples are written as markdown with embedded Rust code blocks, tested via [skeptic](https://github.com/brson/rust-skeptic) (which compiles and runs code blocks from markdown).
8+
9+
## Build & Test Commands
10+
11+
```bash
12+
# Build the book
13+
make build # or: mdbook build
14+
15+
# Run all tests (skeptic + spellcheck)
16+
make test # or: cargo test && ./ci/spellcheck.sh list
17+
18+
# Run only skeptic tests (tests code examples in markdown)
19+
cargo test --test skeptic
20+
21+
# Serve book locally with live reload
22+
make serve # or: mdbook serve --open
23+
24+
# Build + test together
25+
make dev
26+
27+
# xtask alternatives
28+
cargo xtask test all # run all tests
29+
cargo xtask test cargo # cargo tests only
30+
cargo xtask test link # link checking (requires lychee)
31+
cargo xtask book # build book
32+
cargo xtask book serve # serve book
33+
34+
# Link checking
35+
cargo xtask test link # or: lychee --base . --config ./ci/lychee.toml .
36+
37+
# Spellcheck
38+
./ci/spellcheck.sh # interactive; add words to ci/dictionary.txt
39+
```
40+
41+
Required tools: `cargo install mdbook@0.4.43 lychee@0.17.0`
42+
43+
## Architecture
44+
45+
### Two example patterns
46+
47+
This project has two ways examples are tested. **Do not change dependency versions in root `Cargo.toml`** — if a dependency needs upgrading, migrate the affected examples to a standalone crate instead.
48+
49+
#### Pattern 1: Skeptic-tested inline code (legacy)
50+
51+
Code blocks live directly in markdown files under `src/`. The `build.rs` walks `src/` for `.md` files and `skeptic::generate_doc_tests()` compiles each code block as a test. All dependencies come from the root `Cargo.toml` `[dependencies]`.
52+
53+
Example (`src/text/regex/replace.md`):
54+
~~~markdown
55+
```rust,edition2018
56+
use regex::Regex;
57+
fn main() {
58+
// ...
59+
}
60+
```
61+
~~~
62+
63+
- Annotations: `edition2018`, `edition2021`, `edition2024`, `no_run`, `should_panic`, `ignore`
64+
- Hidden boilerplate lines prefixed with `# ` (visible to skeptic, hidden in book)
65+
- Dependencies must exist in root `Cargo.toml` `[dependencies]`
66+
67+
#### Pattern 2: Standalone workspace crates (preferred for new/migrated examples)
68+
69+
Code lives in `crates/` as its own package with independent `Cargo.toml`. Markdown in `src/` pulls the code in via mdBook `{{#include}}` directives. The path is excluded from skeptic in `build.rs`.
70+
71+
Existing crates:
72+
- `crates/algorithms/randomness/` — binaries in `src/bin/`, uses `workspace = true` deps
73+
- `crates/development_tools/debugging/tracing/` — single binary
74+
- `crates/web/` — library with modules, has its own pinned dependency versions
75+
76+
Example markdown (`src/algorithms/randomness/rand.md`):
77+
~~~markdown
78+
```rust
79+
{{#include ../../../crates/algorithms/randomness/src/bin/rand.rs }}
80+
```
81+
~~~
82+
83+
Line-range includes are also supported (e.g., `{{#include .../passwd.rs::15 }}` to hide test code).
84+
85+
### Migrating a skeptic example to a standalone crate
86+
87+
When a dependency version needs to change, migrate the affected examples rather than bumping the version in root `Cargo.toml`. Steps:
88+
89+
1. **Create the crate** at `crates/<category>/<name>/` with its own `Cargo.toml`. Use `workspace = true` for shared deps when possible, or pin versions independently.
90+
2. **Move code** from the markdown code block into `src/bin/<example>.rs` (one binary per example) or `src/lib.rs` for library-style examples.
91+
3. **Add to workspace** in root `Cargo.toml`: add the path to `[workspace] members`.
92+
4. **Update markdown** to use `{{#include}}` instead of inline code:
93+
~~~markdown
94+
```rust
95+
{{#include ../../../crates/<category>/<name>/src/bin/<example>.rs }}
96+
```
97+
~~~
98+
Use relative path from the markdown file's location to the crate source.
99+
5. **Exclude from skeptic** in `build.rs`:
100+
- For an entire directory: add to `REMOVED_PREFIXES` (e.g., `"./src/<category>/<name>/"`)
101+
- For a single file: add to `REMOVED_TESTS` (e.g., `"./src/<category>/<name>/<file>.md"`)
102+
6. **Test**: run `cargo test -p <crate-name>` for the new crate and `cargo test --test skeptic` to confirm nothing else broke.
103+
104+
### Key files
105+
106+
- `Cargo.toml` — root package with skeptic-tested dependencies and workspace member list
107+
- `build.rs` — discovers markdown for skeptic; `REMOVED_TESTS` and `REMOVED_PREFIXES` exclude migrated examples
108+
- `book.toml` — mdBook configuration
109+
- `.cargo/config.toml` — defines `cargo xtask` alias
110+
- `xtask/` — task runner for build, test, and link checking
111+
112+
## Writing Examples
113+
114+
- Examples should be complete, compilable, and use `?` for error handling (not `unwrap`)
115+
- Avoid glob imports so readers can see which traits are used
116+
- Mark examples needing external services with `no_run`
117+
- Hide boilerplate with `# ` prefix (hidden from book, visible to skeptic)
118+
- Prefer creating standalone crates for new examples over adding dependencies to root `Cargo.toml`

rust-cookbook/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[workspace]
2-
members = ["crates/algorithms/*", "crates/development_tools/debugging/tracing", "crates/web", "xtask"]
2+
members = ["crates/algorithms/*", "crates/concurrency/*", "crates/development_tools/debugging/tracing", "crates/web", "xtask"]
33

44
[workspace.package]
55
edition = "2024"

rust-cookbook/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ test: ## Run all tests
2020
dev: build test ## Build and test (development workflow)
2121
@echo "Development build complete!"
2222

23-
deploy: dev ## Deploy to GitHub Pages (requires maintainer permissions)
23+
deploy: clean dev ## Deploy to GitHub Pages (requires maintainer permissions)
2424
./scripts/deploy.sh
2525

2626
deploy-skip-tests: build ## Deploy to GitHub Pages without running tests

rust-cookbook/build.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
use walkdir::WalkDir;
22

33
const REMOVED_TESTS: &[&str] = &[
4+
"./src/about.md",
45
"./src/web/clients/requests/header.md",
56
"./src/web/clients/api/rate-limited.md",
7+
"./src/concurrency/parallel/rayon-parallel-sort.md",
68
];
79

810
const REMOVED_PREFIXES: &[&str] = &[

rust-cookbook/crates/algorithms/randomness/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,5 @@ license.workspace = true
77
publish.workspace = true
88

99
[dependencies]
10-
rand.workspace = true
11-
rand_distr.workspace = true
10+
rand = "0.10"
11+
rand_distr = "0.6"

rust-cookbook/crates/algorithms/randomness/src/bin/choose.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use rand::Rng;
1+
use rand::RngExt;
22

33
const CHARSET: &[u8] = b"ABCDEFGHIJKLMNOPQRSTUVWXYZ\
44
abcdefghijklmnopqrstuvwxyz\

rust-cookbook/crates/algorithms/randomness/src/bin/custom.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#![allow(dead_code)]
2-
use rand::Rng;
2+
use rand::{Rng, RngExt};
33

44
#[derive(Debug)]
55
struct Point {

rust-cookbook/crates/algorithms/randomness/src/bin/passwd.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use rand::{distr::Alphanumeric, Rng};
1+
use rand::{distr::Alphanumeric, RngExt};
22

33
fn main() {
44
let password = generate_password();
Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,18 @@
1-
use rand::Rng;
1+
use rand::RngExt;
22

33
fn main() {
44
let mut rng = rand::rng();
55
let random_number: u32 = rng.random();
66
println!("Random number: {random_number}");
77
}
8+
9+
#[cfg(test)]
10+
mod tests {
11+
use super::*;
12+
13+
#[test]
14+
fn test_random_number() {
15+
let mut rng = rand::rng();
16+
let _: u32 = rng.random();
17+
}
18+
}

rust-cookbook/crates/algorithms/randomness/src/bin/random_range.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use rand::Rng;
1+
use rand::RngExt;
22

33
fn main() {
44
let mut rng = rand::rng();

0 commit comments

Comments
 (0)