| name | rust |
| description | Coding style and formatting rules for Rust code. Use this whenever modifying any Rust files. |
Skill: rust
Formatting rules
- Multi-line statements (blocks or those using brackets) must have one empty line between them and other code on the same indentation level, above and beyond.
Dependency Injection Pattern
The project uses an on-the-fly dependency injection system based on Context and Injectable traits.
Core Traits
Context: a trait implemented by AppState that provides access to core infrastructure (Database, Config, Queue, etc.).
Injectable: a trait that services and repositories implement to define how they are constructed from a Context.
ContextExt: provides the .build::<T>() method on any context to instantiate an Injectable type.
Creating a New Service or Repository
- Define your struct.
- Implement
Injectable for it.
- Use
ctx.build::<OtherType>()? to resolve dependencies that also implement Injectable.
- Use
ctx.some_client() or similar for core infrastructure dependencies provided by Context.
Example:
impl Injectable for MyService {
fn inject(ctx: &dyn Context) -> Result<Self> {
Ok(Self {
db: ctx.database(),
repo: Arc::new(ctx.build::<MyRepository>()?),
osm: Arc::new(ctx.build::<OsmClient>()?),
})
}
}
Using Services in Actions
In Actix-Web handlers, use the build method on the Data<AppState>:
pub async fn my_action(state: Data<AppState>) -> Result<Json<...>> {
let service = state.build::<MyService>()?;
let result = service.do_something().await?;
Ok(Json(result))
}
Error Handling
- Don't log where you throw: avoid logging errors (e.g.,
error! or warn!) in services, repositories, or logic that simply detects or propagates the error.
- Log at the boundary: errors should be logged once at the application boundary (e.g., in Actix-Web's
ResponseError implementation).
- Provide context: when creating errors, include enough information (e.g., field names, IDs) so the person reading the log can identify the cause without needing a stack trace.
Development Workflow
- After implementing the required changes, verify code integrity by running
make format check using a sub-agent.