mirror of
https://github.com/teloxide/teloxide.git
synced 2024-12-22 14:35:36 +01:00
3.5 KiB
3.5 KiB
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
Generics are always written with where
.
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 { ... }
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> { ... }
Comments
- Comments must describe what your code does and mustn't describe how your code does it and bla-bla-bla. Be sure that your comments follow the grammar, including punctuation, the first capital letter and so on.
Bad:
/// this function make request to telegram
pub fn make_request(url: &str) -> String { ... }
Good:
/// This function makes a request to Telegram.
pub fn make_request(url: &str) -> String { ... }
- Also, link resources in your comments when possible:
/// Download a file from Telegram.
///
/// `path` can be obtained from the [`Bot::get_file`].
///
/// To download into [`AsyncWrite`] (e.g. [`tokio::fs::File`]), see
/// [`Bot::download_file`].
///
/// [`Bot::get_file`]: crate::bot::Bot::get_file
/// [`AsyncWrite`]: tokio::io::AsyncWrite
/// [`tokio::fs::File`]: tokio::fs::File
/// [`Bot::download_file`]: crate::Bot::download_file
#[cfg(feature = "unstable-stream")]
pub async fn download_file_stream(
&self,
path: &str,
) -> Result<impl Stream<Item = Result<Bytes, reqwest::Error>>, reqwest::Error>
{
download_file_stream(&self.client, &self.token, path).await
}
Use Self where possible
Bad:
impl ErrorKind {
fn print(&self) {
ErrorKind::Io => println!("Io"),
ErrorKind::Network => println!("Network"),
ErrorKind::Json => println!("Json"),
}
}
Good:
impl ErrorKind {
fn print(&self) {
Self::Io => println!("Io"),
Self::Network => println!("Network"),
Self::Json => println!("Json"),
}
}
More examples
Bad:
impl<'a> AnswerCallbackQuery<'a> {
pub(crate) fn new<C>(bot: &'a Bot, callback_query_id: C) -> AnswerCallbackQuery<'a>
where
C: Into<String>, { ... }
Good:
impl<'a> AnswerCallbackQuery<'a> {
pub(crate) fn new<C>(bot: &'a Bot, callback_query_id: C) -> Self
where
C: Into<String>, { ... }
Naming
- Avoid unnecessary duplication (
Message::message_id
->Message::id
using#[serde(rename = "message_id")]
). - Use a generic parameter name
S
for streams,Fut
for futures,F
for functions (where possible).
Deriving
- Derive
Copy
,Eq
,Hash
,PartialEq
,Clone
,Debug
for public types when possible (note: if the defaultDebug
implementation is weird, you should manually implement it by yourself). - Derive
Default
when there is an algorithm to get a default value for your type.
Misc
- Use
Into<...>
only where there exists at least one conversion and it will be logically to use. - Always mark a function as
#[must_use]
if its return value must be used. Box::pin(async [move] { ... })
instead ofasync [move] { ... }.boxed()
.- Always write
log::<op>!(...)
instead of importinguse log::<op>;
and invoking<op>!(...)
. For example, writelog::info!("blah")
.