mirror of
https://github.com/aljazceru/cdk.git
synced 2026-02-06 21:56:13 +01:00
chore: add code style and rust fmt
This commit is contained in:
187
CODE_STYLE.md
Normal file
187
CODE_STYLE.md
Normal file
@@ -0,0 +1,187 @@
|
||||
# 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<N, T, P, E>(user_id: i32, name: N, title: T, png_sticker: P, emojis: E) -> Self
|
||||
where
|
||||
N: Into<String>,
|
||||
T: Into<String>,
|
||||
P: Into<InputFile>,
|
||||
E: Into<String>,
|
||||
{ ... }
|
||||
|
||||
// BAD
|
||||
pub fn new<N: Into<String>,
|
||||
T: Into<String>,
|
||||
P: Into<InputFile>,
|
||||
E: Into<String>>
|
||||
(user_id: i32, name: N, title: T, png_sticker: P, emojis: E) -> Self { ... }
|
||||
```
|
||||
|
||||
```rust
|
||||
// GOOD
|
||||
impl<T> Trait for Wrap<T>
|
||||
where
|
||||
T: Trait
|
||||
{ ... }
|
||||
|
||||
// BAD
|
||||
impl<T: Trait> Trait for Wrap<T> { ... }
|
||||
```
|
||||
|
||||
## 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<C>(bot: &'a Bot, callback_query_id: C) -> Self
|
||||
where
|
||||
C: Into<String>,
|
||||
{ ... }
|
||||
|
||||
// BAD
|
||||
fn new<C>(bot: &'a Bot, callback_query_id: C) -> AnswerCallbackQuery<'a>
|
||||
where
|
||||
C: Into<String>,
|
||||
{ ... }
|
||||
}
|
||||
```
|
||||
|
||||
**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::<op>!(...)` instead of importing `use tracing::<op>;` and invoking `<op>!(...)`.
|
||||
|
||||
```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::{};
|
||||
|
||||
// Re-exports are treated as item definitions rather than imports, so they go
|
||||
// after imports and modules. Use them sparingly.
|
||||
pub use crate::x::Z;
|
||||
```
|
||||
|
||||
## 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 { .. }
|
||||
}
|
||||
```
|
||||
|
||||
## 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 => (),
|
||||
}
|
||||
```
|
||||
9
rustfmt.toml
Normal file
9
rustfmt.toml
Normal file
@@ -0,0 +1,9 @@
|
||||
tab_spaces = 4
|
||||
newline_style = "Auto"
|
||||
reorder_imports = true
|
||||
reorder_modules = true
|
||||
reorder_impl_items = false
|
||||
indent_style = "Block"
|
||||
normalize_comments = false
|
||||
imports_granularity = "Module"
|
||||
group_imports = "StdExternalCrate"
|
||||
Reference in New Issue
Block a user