Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add more #[must_use] attributes for appropriate functions #457

Merged
merged 2 commits into from Jul 22, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/dispatching/dialogue/storage/trace_storage.rs
Expand Up @@ -18,11 +18,12 @@ pub struct TraceStorage<S> {
}

impl<S> TraceStorage<S> {
#[must_use]
#[must_use = "This function is pure, that is does nothing unless its output is used"]
pub fn new(inner: Arc<S>) -> Arc<Self> {
Arc::new(Self { inner })
}

#[must_use = "This function is pure, that is does nothing unless its output is used"]
pub fn into_inner(self) -> Arc<S> {
self.inner
}
Expand Down
2 changes: 2 additions & 0 deletions src/dispatching/stop_token.rs
Expand Up @@ -39,6 +39,7 @@ pub struct AsyncStopFlag(#[pin] Abortable<Pending<()>>);

impl AsyncStopToken {
/// Create a new token/flag pair.
#[must_use = "This function is pure, that is does nothing unless its output is used"]
pub fn new_pair() -> (Self, AsyncStopFlag) {
let (handle, reg) = AbortHandle::new_pair();
let token = Self(handle);
Expand All @@ -56,6 +57,7 @@ impl StopToken for AsyncStopToken {

impl AsyncStopFlag {
/// Returns true if the stop token linked to `self` was used.
#[must_use = "This function is pure, that is does nothing unless its output is used"]
pub fn is_stopped(&self) -> bool {
self.0.is_aborted()
}
Expand Down
22 changes: 22 additions & 0 deletions src/utils/html.rs
Expand Up @@ -8,6 +8,8 @@ use teloxide_core::types::User;
///
/// Passed string will not be automatically escaped because it can contain
/// nested markup.
#[must_use = "This function returns a new string, rather than mutating the argument, so calling it \
without using its output does nothing useful"]
pub fn bold(s: &str) -> String {
format!("<b>{}</b>", s)
}
Expand All @@ -16,6 +18,8 @@ pub fn bold(s: &str) -> String {
///
/// Passed string will not be automatically escaped because it can contain
/// nested markup.
#[must_use = "This function returns a new string, rather than mutating the argument, so calling it \
without using its output does nothing useful"]
pub fn italic(s: &str) -> String {
format!("<i>{}</i>", s)
}
Expand All @@ -24,6 +28,8 @@ pub fn italic(s: &str) -> String {
///
/// Passed string will not be automatically escaped because it can contain
/// nested markup.
#[must_use = "This function returns a new string, rather than mutating the argument, so calling it \
without using its output does nothing useful"]
pub fn underline(s: &str) -> String {
format!("<u>{}</u>", s)
}
Expand All @@ -32,32 +38,42 @@ pub fn underline(s: &str) -> String {
///
/// Passed string will not be automatically escaped because it can contain
/// nested markup.
#[must_use = "This function returns a new string, rather than mutating the argument, so calling it \
without using its output does nothing useful"]
pub fn strike(s: &str) -> String {
format!("<s>{}</s>", s)
}

/// Builds an inline link with an anchor.
///
/// Escapes the passed URL and the link text.
#[must_use = "This function returns a new string, rather than mutating the argument, so calling it \
without using its output does nothing useful"]
pub fn link(url: &str, text: &str) -> String {
format!("<a href=\"{}\">{}</a>", escape(url), escape(text))
}

/// Builds an inline user mention link with an anchor.
#[must_use = "This function returns a new string, rather than mutating the argument, so calling it \
without using its output does nothing useful"]
pub fn user_mention(user_id: i64, text: &str) -> String {
link(format!("tg://user?id={}", user_id).as_str(), text)
}

/// Formats the code block.
///
/// Escapes HTML characters inside the block.
#[must_use = "This function returns a new string, rather than mutating the argument, so calling it \
without using its output does nothing useful"]
pub fn code_block(code: &str) -> String {
format!("<pre>{}</pre>", escape(code))
}

/// Formats the code block with a specific language syntax.
///
/// Escapes HTML characters inside the block.
#[must_use = "This function returns a new string, rather than mutating the argument, so calling it \
without using its output does nothing useful"]
pub fn code_block_with_lang(code: &str, lang: &str) -> String {
format!(
"<pre><code class=\"language-{}\">{}</code></pre>",
Expand All @@ -69,6 +85,8 @@ pub fn code_block_with_lang(code: &str, lang: &str) -> String {
/// Formats the string as an inline code.
///
/// Escapes HTML characters inside the block.
#[must_use = "This function returns a new string, rather than mutating the argument, so calling it \
without using its output does nothing useful"]
pub fn code_inline(s: &str) -> String {
format!("<code>{}</code>", escape(s))
}
Expand All @@ -80,10 +98,14 @@ pub fn code_inline(s: &str) -> String {
/// they shoudn't be escaped by the [spec].
///
/// [spec]: https://core.telegram.org/bots/api#html-style
#[must_use = "This function returns a new string, rather than mutating the argument, so calling it \
without using its output does nothing useful"]
pub fn escape(s: &str) -> String {
s.replace('&', "&amp;").replace('<', "&lt;").replace('>', "&gt;")
}

#[must_use = "This function returns a new string, rather than mutating the argument, so calling it \
without using its output does nothing useful"]
pub fn user_mention_or_link(user: &User) -> String {
match user.mention() {
Some(mention) => mention,
Expand Down
26 changes: 26 additions & 0 deletions src/utils/markdown.rs
Expand Up @@ -8,6 +8,8 @@ use teloxide_core::types::User;
///
/// Passed string will not be automatically escaped because it can contain
/// nested markup.
#[must_use = "This function returns a new string, rather than mutating the argument, so calling it \
without using its output does nothing useful"]
pub fn bold(s: &str) -> String {
format!("*{}*", s)
}
Expand All @@ -17,6 +19,8 @@ pub fn bold(s: &str) -> String {
/// Can be safely used with `utils::markdown::underline()`.
/// Passed string will not be automatically escaped because it can contain
/// nested markup.
#[must_use = "This function returns a new string, rather than mutating the argument, so calling it \
without using its output does nothing useful"]
pub fn italic(s: &str) -> String {
if s.starts_with("__") && s.ends_with("__") {
format!(r"_{}\r__", &s[..s.len() - 1])
Expand All @@ -30,6 +34,8 @@ pub fn italic(s: &str) -> String {
/// Can be safely used with `utils::markdown::italic()`.
/// Passed string will not be automatically escaped because it can contain
/// nested markup.
#[must_use = "This function returns a new string, rather than mutating the argument, so calling it \
without using its output does nothing useful"]
pub fn underline(s: &str) -> String {
// In case of ambiguity between italic and underline entities
// ‘__’ is always greadily treated from left to right as beginning or end of
Expand All @@ -47,39 +53,51 @@ pub fn underline(s: &str) -> String {
///
/// Passed string will not be automatically escaped because it can contain
/// nested markup.
#[must_use = "This function returns a new string, rather than mutating the argument, so calling it \
without using its output does nothing useful"]
pub fn strike(s: &str) -> String {
format!("~{}~", s)
}

/// Builds an inline link with an anchor.
///
/// Escapes `)` and ``` characters inside the link url.
#[must_use = "This function returns a new string, rather than mutating the argument, so calling it \
without using its output does nothing useful"]
pub fn link(url: &str, text: &str) -> String {
format!("[{}]({})", text, escape_link_url(url))
}

/// Builds an inline user mention link with an anchor.
#[must_use = "This function returns a new string, rather than mutating the argument, so calling it \
without using its output does nothing useful"]
pub fn user_mention(user_id: i64, text: &str) -> String {
link(format!("tg://user?id={}", user_id).as_str(), text)
}

/// Formats the code block.
///
/// Escapes ``` and `\` characters inside the block.
#[must_use = "This function returns a new string, rather than mutating the argument, so calling it \
without using its output does nothing useful"]
pub fn code_block(code: &str) -> String {
format!("```\n{}\n```", escape_code(code))
}

/// Formats the code block with a specific language syntax.
///
/// Escapes ``` and `\` characters inside the block.
#[must_use = "This function returns a new string, rather than mutating the argument, so calling it \
without using its output does nothing useful"]
pub fn code_block_with_lang(code: &str, lang: &str) -> String {
format!("```{}\n{}\n```", escape(lang), escape_code(code))
}

/// Formats the string as an inline code.
///
/// Escapes ``` and `\` characters inside the block.
#[must_use = "This function returns a new string, rather than mutating the argument, so calling it \
without using its output does nothing useful"]
pub fn code_inline(s: &str) -> String {
format!("`{}`", escape_code(s))
}
Expand All @@ -88,6 +106,8 @@ pub fn code_inline(s: &str) -> String {
/// v2][spec] message style.
///
/// [spec]: https://core.telegram.org/bots/api#html-style
#[must_use = "This function returns a new string, rather than mutating the argument, so calling it \
without using its output does nothing useful"]
pub fn escape(s: &str) -> String {
s.replace('_', r"\_")
.replace('*', r"\*")
Expand All @@ -111,16 +131,22 @@ pub fn escape(s: &str) -> String {

/// Escapes all markdown special characters specific for the inline link URL
/// (``` and `)`).
#[must_use = "This function returns a new string, rather than mutating the argument, so calling it \
without using its output does nothing useful"]
pub fn escape_link_url(s: &str) -> String {
s.replace('`', r"\`").replace(')', r"\)")
}

/// Escapes all markdown special characters specific for the code block (``` and
/// `\`).
#[must_use = "This function returns a new string, rather than mutating the argument, so calling it \
without using its output does nothing useful"]
pub fn escape_code(s: &str) -> String {
s.replace('\\', r"\\").replace('`', r"\`")
}

#[must_use = "This function returns a new string, rather than mutating the argument, so calling it \
without using its output does nothing useful"]
pub fn user_mention_or_link(user: &User) -> String {
match user.mention() {
Some(mention) => mention,
Expand Down