# Code style This is a description of a coding style that every contributor **must** follow. Please, read the whole document before you start pushing code. ## Generics All trait bounds should be written in `where`: ```rust // GOOD pub fn new(user_id: i32, name: N, title: T, png_sticker: P, emojis: E) -> Self where N: Into, T: Into, P: Into, E: Into, { ... } // BAD pub fn new, T: Into, P: Into, E: Into> (user_id: i32, name: N, title: T, png_sticker: P, emojis: E) -> Self { ... } ``` ```rust // GOOD impl Trait for Wrap where T: Trait { ... } // BAD impl Trait for Wrap { ... } ``` ## Use `Self` where possible When referring to the type for which block is implemented, prefer using `Self`, rather than the name of the type: ```rust impl ErrorKind { // GOOD fn print(&self) { Self::Io => println!("Io"), Self::Network => println!("Network"), Self::Json => println!("Json"), } // BAD fn print(&self) { ErrorKind::Io => println!("Io"), ErrorKind::Network => println!("Network"), ErrorKind::Json => println!("Json"), } } ``` ```rust impl<'a> AnswerCallbackQuery<'a> { // GOOD fn new(bot: &'a Bot, callback_query_id: C) -> Self where C: Into, { ... } // BAD fn new(bot: &'a Bot, callback_query_id: C) -> AnswerCallbackQuery<'a> where C: Into, { ... } } ``` **Rationale:** `Self` is generally shorter and it's easier to copy-paste code or rename the type. ## Deriving traits (apply only to libraries) Derive `Debug`, `Clone`, `Copy`, `PartialEq`, `Eq` and `Hash` for public types when possible (in this order). **Rationale:** these traits can be useful for users and can be implemented for most types. Derive `Default` when there is a reasonable default value for the type. ## Full paths for logging Always write `tracing::!(...)` instead of importing `use tracing::;` and invoking `!(...)`. ```rust // GOOD tracing::warn!("Everything is on fire"); // BAD use tracing::warn; warn!("Everything is on fire"); ``` **Rationale:** - Less polluted import blocks - Uniformity ## `&str` -> `String` conversion Prefer using `.to_string()` or `.to_owned()`, rather than `.into()`, `String::from`, etc. **Rationale:** uniformity, intent clarity. ## Order of imports ```rust // First core, alloc and/or std use core::fmt; use std::{...}; // Second, external crates (both crates.io crates and other rust-analyzer crates). use crate_foo::{ ... }; use crate_bar::{ ... }; // If applicable, the current sub-modules mod x; mod y; // Finally, the internal crate modules and submodules use crate::{}; use super::{}; use self::y::Y; ``` ## Import Style When implementing traits from `core::fmt`/`std::fmt` import the module: ```rust // GOOD use core::fmt; impl fmt::Display for RenameError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { .. } } // BAD impl core::fmt::Display for RenameError { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { .. } } ``` When imports sub-modules: ```rust // GOOD mod x; use self::x::Y; // BAD mod x; use x::Y; ``` ## If-let Avoid the `if let ... { } else { }` construct if possible, use `match` instead: ```rust // GOOD match ctx.expected_type.as_ref() { Some(expected_type) => completion_ty == expected_type && !expected_type.is_unit(), None => false, } // BAD if let Some(expected_type) = ctx.expected_type.as_ref() { completion_ty == expected_type && !expected_type.is_unit() } else { false } ``` Use `if let ... { }` when a match arm is intentionally empty: ```rust // GOOD if let Some(expected_type) = this.as_ref() { // Handle it } // BAD match this.as_ref() { Some(expected_type) => { // Handle it }, None => (), } ``` ## Sub-modules Avoid the `mod x { .. }` construct if possible. Instead, crate a file `x.rs` and define it with `mod x;` **This applies to all sub-modules except `tests` and `benches`.** ```rust // GOOD mod x; // BAD mod x { .. } ``` ```rust // GOOD #[cfg(test)] mod tests { .. } // BAD mod tests; ``` ```rust // GOOD #[cfg(bench)] mod benches { .. } // BAD mod benches; ```