# Code Style Guide This project follows a **Modified Allman** brace and formatting style, applied to Rust. It prioritizes **visual clarity, symmetry, and logical separation of blocks** over strict line compactness. This file is the canonical style reference; the style bullets in [CONTRIBUTING.md](CONTRIBUTING.md) are a summary of it. --- ## Key principles - Indentation with **tabs** (width = 4). - **Opening braces `{`** start on their own line — for `fn`, `impl`, `struct`, `enum`, `trait`, `mod`, `if`, `for`, `while`, `loop` and `match`. - **`} else {`** and **`} else if … {`** stay on the same line for compact flow. - **Spaces inside parentheses only when non-empty:** - `( arg1, arg2 )` - `main()` - **Spaces inside attribute brackets only when non-empty:** `#[ derive( Clone, Debug ) ]`, `#[ cfg( test ) ]`. - **No spaces inside generics:** `Vec`, `Option`, `Element`. - **Types, traits, and enum variants:** PascalCase. - **Functions, methods, variables, and modules:** snake_case (the Rust convention; `rustc` warns on anything else). - **Constants and statics:** UPPER_CASE_WITH_UNDERSCORES. - **Aligned columns** in consecutive struct fields, match arms, or `let` groups where it aids scanning. - **Comments in English**, only where the code cannot say it itself. --- ## Examples ### `if / else` structure ```rust if condition { do_something(); } else if other_condition { do_other_thing(); } else { do_something_else( arg1, arg2 ); } ``` ### `match` structure ```rust match points.len() { 0 => None, 1 => Some( points[0].value ), n => Some( total / n as f32 ), } ``` ### Error handling Rust has no `try / catch`; recoverable errors travel as `Result` and propagate with `?`. The block style applies to the `match` when a result is handled in place: ```rust fn load_config( path: &Path ) -> Result { let text = std::fs::read_to_string( path )?; match toml::from_str( &text ) { Ok( cfg ) => Ok( cfg ), Err( e ) => Err( ConfigError::Parse( e ) ), } } ``` `if let` follows the same brace rules as `if`: ```rust if let Some( ( rgba, w, h ) ) = icon( "general/right" ) { it = it.trailing_icon( rgba, w, h ); } ``` ### Structs, impls, and attributes ```rust #[ derive( Clone, Debug ) ] pub struct DataPoint { value: f32, label: String, } impl DataPoint { pub fn new( value: f32, label: impl Into ) -> Self { Self { value, label: label.into(), } } pub fn scaled( &self, factor: f32 ) -> f32 { if factor <= 0.0 { self.value } else { self.value * factor } } } ``` ### `main()` function ```rust fn main() { let analyzer = DataAnalyzer::new( "results.csv" ); if let Err( e ) = analyzer.process_and_report() { eprintln!( "Error: {e}" ); std::process::exit( 1 ); } } ``` --- ## Tooling: do not run `cargo fmt` `rustfmt` cannot express this style, so **never run `cargo fmt` on this codebase** — it would rewrite every file into the default style. Specifically: - There is **no rustfmt option for spaces inside parentheses or attribute brackets** (the historical `spaces_within_parens` options were removed from rustfmt). - The item brace styles (`brace_style`, `control_brace_style`) are **unstable, nightly-only** options. - Even on nightly, the combination of Allman opening braces with a compact `} else {` is not representable: `control_brace_style = "AlwaysNextLine"` also pushes `else` onto its own line. The repository ships a `rustfmt.toml` containing only `disable_all_formatting = true`, so an accidental `cargo fmt` — or an editor with format-on-save wired to rustfmt — is a no-op instead of a 40 000-line diff. The mechanically verifiable subset (tab indentation, attribute-bracket spacing) is enforced by `make stylecheck` (`scripts/style-check.sh`), which CI runs on every push; everything else — brace placement, paren spacing, naming — is enforced by review.