diff --git a/README.md b/README.md index b2b3069..ac4902b 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,10 @@ Dokumentace/ │ ├── TEMPLATE.md # New project template specification │ └── prebuild.py # Pre-build script (PyInstaller) │ +├── Rust/ # Rust development guidelines +│ ├── DESIGN_DOCUMENT.md # Guidelines for Rust applications +│ └── DESIGN_DOCUMENT_LIB.md # Guidelines for Rust libraries +│ ├── Project template/ # Reusable files for new projects │ ├── CHANGELOG.md # Changelog template │ └── PROJECT.md # Project documentation template @@ -44,6 +48,8 @@ Each project references these documents so AI assistants operate within consiste |----------|-----------| | Python (application) | `Python/DESIGN_DOCUMENT.md` | | Python (library) | `Python/DESIGN_DOCUMENT_MODULE.md` | +| Rust (application) | `Rust/DESIGN_DOCUMENT.md` | +| Rust (library) | `Rust/DESIGN_DOCUMENT_LIB.md` | ## Key Conventions diff --git a/Rust/DESIGN_DOCUMENT.md b/Rust/DESIGN_DOCUMENT.md new file mode 100644 index 0000000..6ede605 --- /dev/null +++ b/Rust/DESIGN_DOCUMENT.md @@ -0,0 +1,205 @@ +# Rust Application Development Guidelines + +**Document Version:** v1 + +> **Note on Versioning:** +> - This document version is independent — reused across projects +> - **Project version** source of truth: `Cargo.toml` under `[package]` +> - `CHANGELOG.md` uses project version from `Cargo.toml` + +## Related Documents + +- **README.md** — Project overview, build instructions, usage +- **AGENTS.md** — Rules for AI assistants +- **PROJECT.md** — Project goals and current state +- **CHANGELOG.md** — Version history + +--- + +## 1. Code Style + +- **Rust edition:** 2021 +- Format with **rustfmt** — run `cargo fmt` before every commit +- Lint with **clippy** — run `cargo clippy -- -D warnings` before every commit +- **snake_case** functions/variables/modules, **PascalCase** types/traits, **SCREAMING_SNAKE_CASE** constants +- Keep functions short and focused — one responsibility per function + +--- + +## 2. Cargo + +```bash +cargo add # Add runtime dependency +cargo add --dev # Add dev dependency +cargo remove # Remove dependency +cargo build # Debug build +cargo build --release # Release build +cargo run # Run debug build +cargo run --release # Run release build +cargo test # Run all tests +cargo fmt # Format code +cargo clippy -- -D warnings # Lint (treat warnings as errors) +``` + +Never edit `Cargo.toml` dependency versions by hand — use `cargo add`. + +--- + +## 3. Project Structure + +``` +project/ +├── src/ +│ ├── main.rs # Entry point +│ ├── lib.rs # Optional: shared library code +│ └── / +│ └── mod.rs +├── tests/ # Integration tests +├── Cargo.toml +└── Cargo.lock # Commit for applications, not for libraries +``` + +A project may have multiple binaries under `src/bin/`. + +--- + +## 4. Error Handling + +- Use **thiserror** for defining typed errors in library/domain code +- Use **anyhow** for application-level error propagation (`main`, CLI handlers) +- Never use `.unwrap()` in production code — use `?` or explicit handling +- `.expect("reason")` is acceptable only when the invariant is guaranteed and documented + +--- + +## 5. Logging + +Use **tracing** for structured logging. + +```toml +[dependencies] +tracing = "0.1" +tracing-subscriber = { version = "0.3", features = ["env-filter"] } +``` + +```rust +use tracing::{debug, info, warn, error}; + +fn main() { + tracing_subscriber::fmt() + .with_env_filter(tracing_subscriber::EnvFilter::from_default_env()) + .init(); +} +``` + +Control log level via `RUST_LOG` environment variable: + +```bash +RUST_LOG=debug cargo run +RUST_LOG=my_app=info,warn cargo run +``` + +#### Log levels + +| Level | When to use | +|-------|-------------| +| `debug` | Per-item detail: internal state, cache hits, per-item operations | +| `info` | User-visible milestones: process started/finished, file saved | +| `warn` | Recoverable issues: fallback used, unexpected but non-fatal state | +| `error` | Failures the user must know about — operation cannot continue | + +Never use `println!` for debugging or internal logging. + +--- + +## 6. Environment and Secrets + +- Store secrets in `.env` file +- Load via **dotenvy** crate and `std::env::var()` +- Never commit `.env` + +```rust +dotenvy::dotenv().ok(); +let api_key = std::env::var("API_KEY").expect("API_KEY must be set"); +``` + +--- + +## 7. Testing + +- Use Rust's built-in test framework — `#[test]` and `#[cfg(test)]` +- Unit tests live in the same file as the code, in a `mod tests` block +- Integration tests live in `tests/` +- Use `assert_eq!`, `assert!`, `assert_ne!` — no external test frameworks needed +- Test naming: `test__` + +```rust +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_parse_valid_input() { + assert_eq!(parse("42"), Ok(42)); + } +} +``` + +--- + +## 8. Tooling + +| Tool | Purpose | +|------|---------| +| **rustfmt** | Code formatting | +| **clippy** | Linting | +| **cargo test** | Testing | +| **cargo build --release** | Production build | + +Run before every commit: +```bash +cargo fmt +cargo clippy -- -D warnings +cargo test +``` + +--- + +## 9. Distribution + +For standalone executables: + +```bash +cargo build --release +# Binary is at: target/release/ +``` + +For cross-compilation (e.g. Windows from Linux): +```bash +cargo install cross +cross build --release --target x86_64-pc-windows-gnu +``` + +`Cargo.lock` **is committed** for applications — it ensures reproducible builds. + +--- + +## 10. Versioning + +- Follow **semantic versioning**: `MAJOR.MINOR.PATCH` +- Version is defined in `Cargo.toml` under `[package]` +- Always ask before bumping the version — never increment automatically +- Update `CHANGELOG.md` before bumping the version + +--- + +## 11. Documentation and Task Management + +- Keep `PROJECT.md` and `CHANGELOG.md` up to date when making changes + +### Task notation + +```rust +// TODO: one-liner description of a task to be done +// FIXME: one-liner description of a known bug to be fixed +``` diff --git a/Rust/DESIGN_DOCUMENT_LIB.md b/Rust/DESIGN_DOCUMENT_LIB.md new file mode 100644 index 0000000..e1ca28f --- /dev/null +++ b/Rust/DESIGN_DOCUMENT_LIB.md @@ -0,0 +1,241 @@ +# Rust Library Development Guidelines + +**Document Version:** v1 + +> **Note on Versioning:** +> - This document version is independent — reused across projects +> - **Project version** source of truth: `Cargo.toml` under `[package]` +> - `CHANGELOG.md` uses project version from `Cargo.toml` + +## Related Documents + +- **README.md** — Project overview, public API description, installation and usage examples +- **AGENTS.md** — Rules for AI assistants +- **PROJECT.md** — Project goals and current state +- **CHANGELOG.md** — Version history + +--- + +## 1. Code Style + +- **Rust edition:** 2021 +- Format with **rustfmt** — run `cargo fmt` before every commit +- Lint with **clippy** — run `cargo clippy -- -D warnings` before every commit +- **snake_case** functions/variables/modules, **PascalCase** types/traits, **SCREAMING_SNAKE_CASE** constants + +--- + +## 2. Cargo + +```bash +cargo add # Add runtime dependency +cargo add --dev # Add dev dependency +cargo remove # Remove dependency +cargo test # Run all tests +cargo doc --open # Build and open documentation +cargo fmt # Format code +cargo clippy -- -D warnings # Lint (treat warnings as errors) +cargo build # Build to verify compilation +cargo publish # Publish to crates.io +``` + +Never edit `Cargo.toml` dependency versions by hand — use `cargo add`. + +--- + +## 2. Project Structure + +``` +project/ +├── src/ +│ ├── lib.rs # Public API — re-export everything the caller needs +│ ├── error.rs # All public error types +│ └── / +│ └── mod.rs +├── tests/ # Integration tests (test the public API only) +├── examples/ # Usage examples +├── Cargo.toml +└── Cargo.lock # Do NOT commit — add to .gitignore +``` + +No `main.rs` — libraries have no entry point. + +--- + +## 3. Public API + +- Everything intended for external use must be `pub` and re-exported from `lib.rs` +- Use `pub(crate)` for internal items that cross module boundaries +- Internal modules should be private (`mod foo;`) unless they are part of the public API +- Public API must be stable across patch versions; breaking changes require a major version bump +- Use `#[non_exhaustive]` on public enums and structs to allow adding fields without breaking changes + +```rust +// lib.rs — public surface +pub use error::MyError; +pub use client::Client; +pub use types::{Config, Response}; +``` + +--- + +## 4. Error Handling + +- Define all public error types in `src/error.rs` using **thiserror** +- Export all errors from `lib.rs` +- Never use `.unwrap()` — use `?` or explicit handling +- `.expect("reason")` only when the invariant is guaranteed and documented + +```rust +// error.rs +use thiserror::Error; + +#[derive(Debug, Error)] +pub enum MyError { + #[error("invalid input: {0}")] + InvalidInput(String), + #[error("IO error: {0}")] + Io(#[from] std::io::Error), +} +``` + +--- + +## 5. Logging + +This is a library. Libraries must **never configure logging sinks** — that is the responsibility of the consuming application. + +Use **tracing** for instrumentation: + +```toml +[dependencies] +tracing = "0.1" +``` + +```rust +use tracing::{debug, info, warn, error}; + +pub fn do_something() { + debug!("internal detail"); + info!("milestone reached"); +} +``` + +Never call `tracing_subscriber::fmt().init()` or any sink setup inside library code. The consuming application configures the subscriber. + +#### Log levels + +| Level | When to use | +|-------|-------------| +| `debug` | Per-item detail: internal state, cache hits | +| `info` | Significant milestones visible to the consuming application | +| `warn` | Recoverable issues: fallback used, unexpected but non-fatal | +| `error` | Failures the caller must know about | + +--- + +## 6. Environment and Secrets + +Libraries do not read environment variables or `.env` files. Configuration is passed by the caller via arguments or constructor parameters. + +--- + +## 7. Testing + +- Use Rust's built-in test framework — `#[test]` and `#[cfg(test)]` +- Unit tests live in the same file as the code, in a `mod tests` block +- Integration tests in `tests/` test only the public API (as a real consumer would) +- Test naming: `test__` + +```rust +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_parse_valid_input() { + assert_eq!(parse("42"), Ok(42)); + } +} +``` + +`Cargo.lock` is **not committed** for libraries — add it to `.gitignore`. Consumers pin their own dependency graph. + +--- + +## 8. Documentation + +All public items must have doc comments. Use `cargo doc --open` to verify locally. + +```rust +/// Parses a value from a string. +/// +/// # Errors +/// +/// Returns [`MyError::InvalidInput`] if the string is not a valid value. +/// +/// # Examples +/// +/// ``` +/// use my_crate::parse; +/// assert_eq!(parse("42"), Ok(42)); +/// ``` +pub fn parse(s: &str) -> Result { ... } +``` + +`README.md` must contain installation instructions and usage examples for the public API. + +--- + +## 9. Tooling + +| Tool | Purpose | +|------|---------| +| **rustfmt** | Code formatting | +| **clippy** | Linting | +| **cargo test** | Testing | +| **cargo doc** | Documentation | + +Run before every commit: +```bash +cargo fmt +cargo clippy -- -D warnings +cargo test +``` + +--- + +## 10. Distribution + +Build and publish with Cargo: + +```bash +cargo package # Verify what will be published +cargo publish # Publish to crates.io (requires login) +``` + +`Cargo.lock` is **not committed** — add to `.gitignore`. + +--- + +## 11. Versioning + +- Follow **semantic versioning**: `MAJOR.MINOR.PATCH` +- Version is defined in `Cargo.toml` under `[package]` +- Always ask before bumping the version — never increment automatically +- Update `CHANGELOG.md` before bumping the version +- Breaking changes to the public API require a major version bump + +--- + +## 12. Documentation and Task Management + +- Keep `PROJECT.md` and `CHANGELOG.md` up to date when making changes +- `README.md` must contain installation instructions and usage examples for the public API + +### Task notation + +```rust +// TODO: one-liner description of a task to be done +// FIXME: one-liner description of a known bug to be fixed +```