All Rust source code must be formatted with rustfmt and linted with Clippy linter, customized by project settings (.rustfmt.toml
and .clippy.toml
files).
Additional rules, not handled by rustfmt and Clippy are described below.
These should be divided into the following ordered sections:
- modules declarations (
mod
andpub mode
keywords); - imports sections (
use
keyword):std
/core
imports;- external crates imports;
- this crate imports (start with
crate::
); - imports from parent modules (start with
super::
); - imports from sub-modules (start with
self::
).
- re-export sections (
pub use
keyword):std
/core
re-exports;- external crates re-exports;
- this crate re-exports (start with
crate::
); - re-exports from parent modules (start with
super::
); - re-exports from sub-modules (start with
self::
).
A blank line is mandatory between these sections, before and after.
Items must be sorted in alphabetical order inside each section and inside each statement.
If imported trait is not used directly, then it must be underscore imported (as _
) to not pollute the current module's namespace.
Import multiple items in one statement from one location, rather than using multiple statements (usually, controlled by merge_imports
option of rustfmt).
//! Some module.
mod private_stuff;
pub mod public_stuff;
use std::sync::{Arc, Mutex};
use chrono::{DateTime, Utc};
use futures::Future as _;
use serde::{Deserialize, Serialize};
use crate::core::{DynFuture, DynStream};
use super::event;
use self::private_stuff::util;
pub use postgres::Type;
pub use crate::core::util::UnfoldingStream;
pub use super::props::Error;
pub use self::public_stuff::*;
const LIMIT: u8 = 100;
-
No blank lines:
//! Some module. mod private_stuff; pub mod public_stuff;
use std::sync::{Arc, Mutex}; use chrono::{DateTime, Utc}; use futures::Future as _; use serde::{Deserialize, Serialize}; use crate::core::{DynFuture, DynStream}; use super::event; use self::private_stuff::util; pub use postgres::Type; pub use crate::core::util::UnfoldingStream; pub use super::props::Error; pub use self::public_stuff::*;
use std::sync::{Arc, Mutex}; use chrono::{DateTime, Utc}; use futures::Future as _; use serde::{Deserialize, Serialize}; use crate::core::{DynFuture, DynStream}; use super::event; use self::private_stuff::util; pub use postgres::Type; pub use crate::core::util::UnfoldingStream; pub use super::props::Error; pub use self::public_stuff::*;
pub use self::public_stuff::*; const LIMIT: u8 = 100;
-
Not sorted alphabetically:
use serde::{Serialize, Deserialize};
pub mod public_stuff; mod private_stuff; use futures::Future as _; use serde::{Deserialize, Serialize}; use chrono::{DateTime, Utc};
-
Multiple statements for items from the same location:
use chrono::DateTime; use chrono::Utc; use serde::Deserialize; use serde::Serialize;
-
Imported traits implementations without underscore:
use futures::{Future, IntoFuture}; use crate::core::DynFuture; fn do_something() -> DynFuture<i32, ()> { Box::new(Ok(21).into_future().map(|n| n + 1)) }
Attributes on declarations must be sorted in alphabetic order. Items inside attribute must be sorted in alphabetic order too (in the same manner they're sorted by rustfmt inside use
statement).
#[allow(clippy::mut_mut)]
#[derive(smart_default::SmartDefault, Debug, Deserialize, Serialize)]
#[serde(deny_unknown_fields)]
struct User {
#[serde(default)]
id: u64,
}
#[serde(deny_unknown_fields)]
#[derive(smart_default::SmartDefault, Debug, Deserialize, Serialize)]
#[allow(clippy::mut_mut)]
struct User {
id: u64,
}
#[derive(Debug, smart_default::SmartDefault, Serialize, Deserialize)]
struct User {
id: u64,
}
It's recommended to use H1 headers (# Header
) in Rust docs as this way is widely adopted in Rust community. Blank lines before headers must be reduced to a single one.
Bold and italic text should be marked via **
and _
accordingly.
Other code definitions should be referred via [`Entity`]
marking (intra-doc links).
/// Type of [`User`]'s unique identifier.
///
/// # Constraints
///
/// - It **must not be zero**.
/// - It _should not_ overflow [`i64::max_value`] due to usage in database.
struct UserId(u64);
-
H2 header is used at the topmost level:
/// Type of [`User`]'s unique identifier. /// /// ## Constraints /// /// - It **must not be zero**. /// - It _should not_ overflow [`i64::max_value`] due to usage in database. struct UserId(u64);
-
Code definition is not referred correctly:
/// Type of User's unique identifier. /// /// # Constraints /// /// - It **must not be zero**. /// - It _should not_ overflow `i64::max_value` due to usage in database. struct UserId(u64);
-
Incorrect bold/italic marking:
/// Type of [`User`]'s unique identifier. /// /// # Constraints /// /// - It __must not be zero__. /// - It *should not* overflow [`i64::max_value`] due to usage in database. struct UserId(u64);