Code Style Guide¶
Coding conventions for Waremax.
Rust Style¶
Formatting¶
Use rustfmt with default settings:
All code must pass formatting checks:
Linting¶
Use clippy for linting:
Fix all clippy warnings before submitting.
Naming Conventions¶
Types¶
// Structs: PascalCase
pub struct RobotConfig { ... }
// Enums: PascalCase
pub enum TaskStatus { ... }
// Traits: PascalCase, often adjectives
pub trait Schedulable { ... }
// Type aliases: PascalCase
pub type NodeId = u32;
Functions and Methods¶
// Functions: snake_case
fn calculate_distance(from: NodeId, to: NodeId) -> f64 { ... }
// Methods: snake_case
impl Robot {
fn is_idle(&self) -> bool { ... }
fn start_task(&mut self, task: Task) { ... }
}
// Constructors: new or descriptive
impl Robot {
fn new(id: RobotId, config: &RobotConfig) -> Self { ... }
fn from_config(config: &RobotConfig) -> Self { ... }
}
Variables¶
// Variables: snake_case
let robot_count = config.robots.count;
let avg_task_time = total_time / task_count;
// Constants: SCREAMING_SNAKE_CASE
const MAX_QUEUE_SIZE: usize = 100;
const DEFAULT_SPEED: f64 = 1.5;
Code Organization¶
Module Structure¶
crate/
├── lib.rs # Public API
├── module.rs # Single-file module
└── module/ # Multi-file module
├── mod.rs # Module root
├── types.rs # Type definitions
└── impl.rs # Implementations
Import Order¶
// 1. Standard library
use std::collections::HashMap;
// 2. External crates
use serde::{Deserialize, Serialize};
// 3. Crate-level imports
use crate::config::Scenario;
// 4. Module-level imports
use super::Robot;
File Organization¶
// lib.rs structure
//! Crate-level documentation
// Public modules
pub mod config;
pub mod entities;
// Re-exports
pub use config::Scenario;
pub use entities::Robot;
// Private modules
mod internal;
// Tests at end
#[cfg(test)]
mod tests;
Documentation¶
Module Documentation¶
//! Module-level documentation
//!
//! This module provides...
//!
//! # Examples
//!
//! ```
//! use waremax::example;
//! ```
Function Documentation¶
/// Calculate the shortest path between two nodes.
///
/// Uses Dijkstra's algorithm to find the path with
/// minimum total edge weight.
///
/// # Arguments
///
/// * `from` - Starting node ID
/// * `to` - Destination node ID
/// * `map` - Warehouse map graph
///
/// # Returns
///
/// `Some(Path)` if a path exists, `None` otherwise.
///
/// # Examples
///
/// ```
/// let path = shortest_path(NodeId(0), NodeId(5), &map);
/// ```
pub fn shortest_path(from: NodeId, to: NodeId, map: &Map) -> Option<Path> {
// ...
}
Inline Comments¶
// Good: Explain WHY
// Use capacity 2 because paths can cross in both directions
let capacity = 2;
// Bad: Explain WHAT (obvious from code)
// Set capacity to 2
let capacity = 2;
Error Handling¶
Use Result for Recoverable Errors¶
// Good
fn parse_config(yaml: &str) -> Result<Config, ConfigError> {
// ...
}
// Avoid panic for recoverable errors
fn parse_config(yaml: &str) -> Config {
// Don't panic here!
}
Custom Error Types¶
#[derive(Debug, thiserror::Error)]
pub enum ConfigError {
#[error("Missing required field: {0}")]
MissingField(String),
#[error("Invalid value for {field}: {message}")]
InvalidValue { field: String, message: String },
#[error("YAML parsing error: {0}")]
YamlError(#[from] serde_yaml::Error),
}
Error Propagation¶
// Use ? operator
fn load_scenario(path: &Path) -> Result<Scenario, Error> {
let content = fs::read_to_string(path)?;
let config: Config = serde_yaml::from_str(&content)?;
let scenario = config.validate()?;
Ok(scenario)
}
Testing¶
Test Organization¶
// Unit tests in same file
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_basic_functionality() {
// ...
}
}
// Integration tests in tests/ directory
// tests/integration.rs
Test Naming¶
#[test]
fn test_robot_starts_idle() { ... }
#[test]
fn test_task_allocation_selects_nearest() { ... }
#[test]
fn test_invalid_config_returns_error() { ... }
Test Structure¶
#[test]
fn test_something() {
// Arrange
let input = create_test_input();
// Act
let result = function_under_test(input);
// Assert
assert_eq!(result, expected);
}
Pull Requests¶
Commit Messages¶
Types: feat, fix, docs, style, refactor, test, chore
Examples:
feat(policies): add weighted allocation policy
fix(routing): handle disconnected graph case
docs(readme): update installation instructions
refactor(metrics): simplify collector interface
PR Description¶
Include:
- What changes were made
- Why the changes were needed
- How to test the changes
- Breaking changes (if any)
Review Process¶
- All tests must pass
- Code must be formatted
- No clippy warnings
- At least one approval required