diff --git a/code_style_guide.md b/code_style_guide.md index 1f7e45f..4e93f86 100755 --- a/code_style_guide.md +++ b/code_style_guide.md @@ -1,169 +1,136 @@ # Code Style Guide -This project follows a **Modified Allman** brace and formatting style. -It prioritizes **visual clarity, symmetry, and logical separation of blocks** over strict line compactness. +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. --- -## Overview +## Key principles -### Key Principles -- Indentation with **tabs** (width = 4). -- **Opening braces `{`** always start on a new line. -- **`} else {`** and **`} catch {`** appear on the same line for compact flow. -- **Spaces inside parentheses only when non-empty:** - - `( arg1, arg2 )` - - `main()` -- **Classes and structs:** PascalCase -- **Variables, objects, and functions:** camelCase -- **Constants/macros:** UPPER_CASE_WITH_UNDERSCORES +- 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 -```cpp -if ( condition ) + +```rust +if condition { - doSomething(); + do_something(); +} else if other_condition { + do_other_thing(); } else { - doSomethingElse( arg1, arg2 ); + do_something_else( arg1, arg2 ); } ``` -### `try / catch` structure -```cpp -try +### `match` structure + +```rust +match points.len() { - runOperation(); -} catch ( const std::exception& ex ) { - handleError( ex ); + 0 => None, + 1 => Some( points[0].value ), + n => Some( total / n as f32 ), } ``` -### Class and method naming -```cpp -class DataAnalyzer +### 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 { -public: - DataAnalyzer( const std::string& filePath ) - : filePath( filePath ) + let text = std::fs::read_to_string( path )?; + match toml::from_str( &text ) { + Ok( cfg ) => Ok( cfg ), + Err( e ) => Err( ConfigError::Parse( e ) ), } +} +``` - void processDataAndGenerateReport() +`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 { - try + Self { - loadDataFromFile( filePath ); - analyzeResultsAndPrintSummary(); - } catch ( const std::runtime_error& error ) { - std::cerr << "Error: " << error.what() << std::endl; + value, + label: label.into(), } } -private: - std::string filePath; - - void loadDataFromFile( const std::string& path ) + pub fn scaled( &self, factor: f32 ) -> f32 { - if ( path.empty() ) + if factor <= 0.0 { - throw std::runtime_error( "File path cannot be empty." ); + self.value } else { - std::cout << "Loading data from: " << path << std::endl; + self.value * factor } } - - void analyzeResultsAndPrintSummary() - { - std::cout << "Analyzing data..." << std::endl; - std::cout << "Summary: OK" << std::endl; - } -}; +} ``` ### `main()` function -```cpp -int main() + +```rust +fn main() { - DataAnalyzer analyzer( "results.csv" ); + let analyzer = DataAnalyzer::new( "results.csv" ); - try + if let Err( e ) = analyzer.process_and_report() { - analyzer.processDataAndGenerateReport(); - } catch ( const std::exception& ex ) { - std::cerr << "Unhandled exception: " << ex.what() << std::endl; + eprintln!( "Error: {e}" ); + std::process::exit( 1 ); } - - return 0; } ``` --- -## `.clang-format` configuration +## Tooling: do not run `cargo fmt` -Save this file as `.clang-format` in your project root: +`rustfmt` cannot express this style, so **never run `cargo fmt` on this codebase** — it would rewrite every file into the default style. Specifically: -```yaml -# === Style: Modified Allman (tabs, compact else/catch, and selective parentheses spacing) === -# Naming conventions: -# · Classes and structs: PascalCase (e.g., MyClass, PlayerController) -# · Variables, objects, and functions: camelCase (e.g., myVariable, calculateScore) -# · Constants or macros: UPPER_CASE_WITH_UNDERSCORES -# · if/else and try/catch share the same brace layout: -# if ( condition ) -# { -# ... -# } else { -# ... -# } -# try -# { -# ... -# } catch ( const std::exception& e ) { -# ... -# } +- 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. -BasedOnStyle: LLVM - -IndentWidth: 4 -UseTab: Always - -BraceWrapping: - AfterClass: true - AfterControlStatement: true - AfterEnum: true - AfterFunction: true - AfterNamespace: true - AfterStruct: true - AfterUnion: true - BeforeCatch: false - BeforeElse: false - IndentBraces: false - SplitEmptyFunction: false - SplitEmptyRecord: false - SplitEmptyNamespace: false - -AllowShortIfStatementsOnASingleLine: false -AllowShortLoopsOnASingleLine: false -AllowShortFunctionsOnASingleLine: false - -SpaceBeforeParens: Always -SpaceInEmptyParentheses: false -SpaceInParens: true -SpacesInAngles: false -SpacesInCStyleCastParentheses: true -SpacesInSquareBrackets: false - -KeepEmptyLinesAtTheStartOfBlocks: true -ColumnLimit: 0 -AlignConsecutiveAssignments: true -AlignConsecutiveDeclarations: true -AlignEscapedNewlines: Left -AlignOperands: true -AlignTrailingComments: true - -BreakBeforeBraces: Allman +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. Style is enforced by review, not by a formatter. diff --git a/rustfmt.toml b/rustfmt.toml new file mode 100644 index 0000000..627fdb5 --- /dev/null +++ b/rustfmt.toml @@ -0,0 +1,4 @@ +# This codebase uses the Modified Allman style described in code_style_guide.md, +# which rustfmt cannot express. Formatting is disabled so an accidental +# `cargo fmt` (or editor format-on-save) is a no-op. +disable_all_formatting = true