Files
ltk/code_style_guide.md
Pedro M. de Echanove Pasquin a7f953ca42
Some checks failed
CI / build + test (push) Has been cancelled
CI / cargo audit (push) Has been cancelled
layout: adaptive grid and vertical flex; enforce the mechanical style rules
grid_min_cell( width ) adds the adaptive mode WrapGrid was missing: instead of a fixed column count, the count is derived at layout time from the available width so every cell is at least `width` wide (any Length, so a fluid threshold works; never fewer than one column), re-derived on every resize. Cells then share the width equally, and WrapGrid::max_columns( n ) caps the derived count so cells grow instead of multiplying on very wide surfaces — the cap only applies to the adaptive mode, grid( n ) keeps the fixed behaviour untouched. Four new layout tests cover width derivation, spacing accounting, the one-column floor and the cap; the row-wrap assertions check X positions rather than Y because zero-height spacer children produce zero-height rows.
flex( child ) now distributes leftover height inside a Column, mirroring its leftover-width behaviour in a Row: flex children join the weight pool alongside weight-only spacers and y-scrolls, draw their child inside the allocated share at full inner width, and contribute zero to the column's natural height exactly like a row counts flex width. This closes the documented "vertical flex is not yet implemented" gap; the Flex rustdoc and the widgets.md entry now describe both axes.
Add scripts/style-check.sh and a make stylecheck target, wired into CI: mechanical verification of the grep-checkable subset of code_style_guide.md — tab indentation and spaces inside attribute brackets — with comment lines skipped so prose may cite raw attribute syntax. To turn the check on green, the 82 unspaced attribute sites across 24 files (#[test], #[derive(...)], #[cfg(...)], #[allow(...)]) were normalized to the spaced form. CONTRIBUTING and the style guide reference the new target; brace placement and paren spacing remain review concerns.
2026-07-30 22:20:21 +02:00

3.8 KiB
Executable File

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 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<String>, Option<i32>, Element<Msg>.
  • 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

if condition
{
	do_something();
} else if other_condition {
	do_other_thing();
} else {
	do_something_else( arg1, arg2 );
}

match structure

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:

fn load_config( path: &Path ) -> Result<Config, ConfigError>
{
	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:

if let Some( ( rgba, w, h ) ) = icon( "general/right" )
{
	it = it.trailing_icon( rgba, w, h );
}

Structs, impls, and attributes

#[ derive( Clone, Debug ) ]
pub struct DataPoint
{
	value: f32,
	label: String,
}

impl DataPoint
{
	pub fn new( value: f32, label: impl Into<String> ) -> 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

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.