clippy: Deny and fix `must_use_candidate`

This commit is contained in:
Adrian Duke 2026-01-13 16:46:21 +00:00 committed by Lorenz Leutgeb
parent 2df32c0099
commit 53cb8da8ff
13 changed files with 54 additions and 0 deletions

View File

@ -86,6 +86,7 @@ clippy.fallible_impl_from = "deny"
clippy.wildcard_enum_match_arm = "deny" clippy.wildcard_enum_match_arm = "deny"
clippy.unneeded_field_pattern = "deny" clippy.unneeded_field_pattern = "deny"
clippy.fn_params_excessive_bools = "deny" clippy.fn_params_excessive_bools = "deny"
clippy.must_use_candidate = "deny"
[profile.container] [profile.container]
inherits = "release" inherits = "release"

View File

@ -43,6 +43,7 @@ pub struct Rev(String);
impl Rev { impl Rev {
/// Return the revision as a string. /// Return the revision as a string.
#[must_use]
pub fn as_str(&self) -> &str { pub fn as_str(&self) -> &str {
&self.0 &self.0
} }

View File

@ -382,6 +382,7 @@ impl DDiff {
} }
/// Returns owned files in the diff. /// Returns owned files in the diff.
#[must_use]
pub fn into_files(self) -> Vec<FileDDiff> { pub fn into_files(self) -> Vec<FileDDiff> {
self.files self.files
} }

View File

@ -33,6 +33,7 @@ impl Error {
Self::Syntax(msg.to_string()) Self::Syntax(msg.to_string())
} }
#[must_use]
pub fn is_eof(&self) -> bool { pub fn is_eof(&self) -> bool {
match self { match self {
Self::UnexpectedEof => true, Self::UnexpectedEof => true,
@ -137,12 +138,14 @@ impl TryFrom<&Hunk<Modification>> for HunkHeader {
} }
impl HunkHeader { impl HunkHeader {
#[must_use]
pub fn old_line_range(&self) -> std::ops::Range<u32> { pub fn old_line_range(&self) -> std::ops::Range<u32> {
let start: u32 = self.old_line_no; let start: u32 = self.old_line_no;
let end: u32 = self.old_line_no + self.old_size; let end: u32 = self.old_line_no + self.old_size;
start..end + 1 start..end + 1
} }
#[must_use]
pub fn new_line_range(&self) -> std::ops::Range<u32> { pub fn new_line_range(&self) -> std::ops::Range<u32> {
let start: u32 = self.new_line_no; let start: u32 = self.new_line_no;
let end: u32 = self.new_line_no + self.new_size; let end: u32 = self.new_line_no + self.new_size;
@ -579,6 +582,7 @@ impl<'a> Writer<'a> {
Ok(()) Ok(())
} }
#[must_use]
pub fn styled(mut self, value: bool) -> Self { pub fn styled(mut self, value: bool) -> Self {
self.styled = value; self.styled = value;
self self

View File

@ -25,12 +25,14 @@ pub struct SyncSettings {
impl SyncSettings { impl SyncSettings {
/// Set sync timeout. Defaults to [`DEFAULT_SYNC_TIMEOUT`]. /// Set sync timeout. Defaults to [`DEFAULT_SYNC_TIMEOUT`].
#[must_use]
pub fn timeout(mut self, timeout: time::Duration) -> Self { pub fn timeout(mut self, timeout: time::Duration) -> Self {
self.timeout = timeout; self.timeout = timeout;
self self
} }
/// Set replicas. /// Set replicas.
#[must_use]
pub fn replicas(mut self, replicas: sync::ReplicationFactor) -> Self { pub fn replicas(mut self, replicas: sync::ReplicationFactor) -> Self {
self.replicas = replicas; self.replicas = replicas;
self self
@ -44,6 +46,7 @@ impl SyncSettings {
/// Use profile to populate sync settings, by adding preferred seeds if no seeds are specified, /// Use profile to populate sync settings, by adding preferred seeds if no seeds are specified,
/// and removing the local node from the set. /// and removing the local node from the set.
#[must_use]
pub fn with_profile(mut self, profile: &Profile) -> Self { pub fn with_profile(mut self, profile: &Profile) -> Self {
// If no seeds were specified, add the preferred seeds. // If no seeds were specified, add the preferred seeds.
if self.seeds.is_empty() { if self.seeds.is_empty() {

View File

@ -51,6 +51,7 @@ pub mod migrate {
use super::MigrateSpinner; use super::MigrateSpinner;
/// Display migration progress via a spinner. /// Display migration progress via a spinner.
#[must_use]
pub fn spinner() -> MigrateSpinner { pub fn spinner() -> MigrateSpinner {
MigrateSpinner::default() MigrateSpinner::default()
} }

View File

@ -17,6 +17,7 @@ use radicle_term::element::Line;
use crate::terminal as term; use crate::terminal as term;
/// Format a node id to be more compact. /// Format a node id to be more compact.
#[must_use]
pub fn node_id_human_compact(node: &NodeId) -> Paint<String> { pub fn node_id_human_compact(node: &NodeId) -> Paint<String> {
let node = node.to_human(); let node = node.to_human();
let start = node.chars().take(7).collect::<String>(); let start = node.chars().take(7).collect::<String>();
@ -26,10 +27,12 @@ pub fn node_id_human_compact(node: &NodeId) -> Paint<String> {
} }
/// Format a node id. /// Format a node id.
#[must_use]
pub fn node_id_human(node: &NodeId) -> Paint<String> { pub fn node_id_human(node: &NodeId) -> Paint<String> {
Paint::new(node.to_human()) Paint::new(node.to_human())
} }
#[must_use]
pub fn addr_compact(address: &Address) -> Paint<String> { pub fn addr_compact(address: &Address) -> Paint<String> {
let host = match address.host() { let host = match address.host() {
HostName::Ip(ip) => ip.to_string(), HostName::Ip(ip) => ip.to_string(),
@ -72,17 +75,20 @@ pub fn command<D: fmt::Display>(cmd: D) -> Paint<String> {
} }
/// Format a COB id. /// Format a COB id.
#[must_use]
pub fn cob(id: &ObjectId) -> Paint<String> { pub fn cob(id: &ObjectId) -> Paint<String> {
Paint::new(format!("{:.7}", id.to_string())) Paint::new(format!("{:.7}", id.to_string()))
} }
/// Format a DID. /// Format a DID.
#[must_use]
pub fn did(did: &Did) -> Paint<String> { pub fn did(did: &Did) -> Paint<String> {
let nid = did.as_key().to_human(); let nid = did.as_key().to_human();
Paint::new(format!("{}{}", &nid[..7], &nid[nid.len() - 7..])) Paint::new(format!("{}{}", &nid[..7], &nid[nid.len() - 7..]))
} }
/// Format a Visibility. /// Format a Visibility.
#[must_use]
pub fn visibility(v: &Visibility) -> Paint<&str> { pub fn visibility(v: &Visibility) -> Paint<&str> {
match v { match v {
Visibility::Public => term::format::positive("public"), Visibility::Public => term::format::positive("public"),
@ -91,6 +97,7 @@ pub fn visibility(v: &Visibility) -> Paint<&str> {
} }
/// Format a policy. /// Format a policy.
#[must_use]
pub fn policy(p: &Policy) -> Paint<String> { pub fn policy(p: &Policy) -> Paint<String> {
match p { match p {
Policy::Allow => term::format::positive(p.to_string()), Policy::Allow => term::format::positive(p.to_string()),
@ -108,6 +115,7 @@ pub fn timestamp(time: impl Into<LocalTime>) -> Paint<String> {
Paint::new(fmt.convert(duration.into())) Paint::new(fmt.convert(duration.into()))
} }
#[must_use]
pub fn bytes(size: usize) -> Paint<String> { pub fn bytes(size: usize) -> Paint<String> {
const KB: usize = 1024; const KB: usize = 1024;
const MB: usize = 1024usize.pow(2); const MB: usize = 1024usize.pow(2);
@ -125,6 +133,7 @@ pub fn bytes(size: usize) -> Paint<String> {
} }
/// Format a ref update. /// Format a ref update.
#[must_use]
pub fn ref_update(update: &RefUpdate) -> Paint<&'static str> { pub fn ref_update(update: &RefUpdate) -> Paint<&'static str> {
match update { match update {
RefUpdate::Updated { .. } => term::format::tertiary("updated"), RefUpdate::Updated { .. } => term::format::tertiary("updated"),
@ -134,6 +143,7 @@ pub fn ref_update(update: &RefUpdate) -> Paint<&'static str> {
} }
} }
#[must_use]
pub fn ref_update_verbose(update: &RefUpdate) -> Paint<String> { pub fn ref_update_verbose(update: &RefUpdate) -> Paint<String> {
match update { match update {
RefUpdate::Created { name, .. } => format!( RefUpdate::Created { name, .. } => format!(
@ -175,6 +185,7 @@ pub struct Identity<'a> {
} }
impl<'a> Identity<'a> { impl<'a> Identity<'a> {
#[must_use]
pub fn new(profile: &'a Profile) -> Self { pub fn new(profile: &'a Profile) -> Self {
Self { Self {
profile, profile,
@ -183,11 +194,13 @@ impl<'a> Identity<'a> {
} }
} }
#[must_use]
pub fn short(mut self) -> Self { pub fn short(mut self) -> Self {
self.short = true; self.short = true;
self self
} }
#[must_use]
pub fn styled(mut self) -> Self { pub fn styled(mut self) -> Self {
self.styled = true; self.styled = true;
self self
@ -227,6 +240,7 @@ pub struct Author<'a> {
} }
impl<'a> Author<'a> { impl<'a> Author<'a> {
#[must_use]
pub fn new(nid: &'a NodeId, profile: &Profile, verbose: bool) -> Author<'a> { pub fn new(nid: &'a NodeId, profile: &Profile, verbose: bool) -> Author<'a> {
let alias = profile.alias(nid); let alias = profile.alias(nid);
@ -238,10 +252,12 @@ impl<'a> Author<'a> {
} }
} }
#[must_use]
pub fn alias(&self) -> Option<term::Label> { pub fn alias(&self) -> Option<term::Label> {
self.alias.as_ref().map(|a| a.to_string().into()) self.alias.as_ref().map(|a| a.to_string().into())
} }
#[must_use]
pub fn you(&self) -> Option<term::Label> { pub fn you(&self) -> Option<term::Label> {
if self.you { if self.you {
Some(term::format::primary("(you)").dim().italic().into()) Some(term::format::primary("(you)").dim().italic().into())
@ -256,6 +272,7 @@ impl<'a> Author<'a> {
/// * `(<did>, (you))` -- the `Author` is the local peer and has no alias /// * `(<did>, (you))` -- the `Author` is the local peer and has no alias
/// * `(<alias>, <did>)` -- the `Author` is another peer and has an alias /// * `(<alias>, <did>)` -- the `Author` is another peer and has an alias
/// * `(<blank>, <did>)` -- the `Author` is another peer and has no alias /// * `(<blank>, <did>)` -- the `Author` is another peer and has no alias
#[must_use]
pub fn labels(self) -> (term::Label, term::Label) { pub fn labels(self) -> (term::Label, term::Label) {
let node_id = if self.verbose { let node_id = if self.verbose {
term::format::node_id_human(self.nid) term::format::node_id_human(self.nid)
@ -274,6 +291,7 @@ impl<'a> Author<'a> {
(alias, author) (alias, author)
} }
#[must_use]
pub fn line(self) -> Line { pub fn line(self) -> Line {
let (alias, author) = self.labels(); let (alias, author) = self.labels();
Line::spaced([alias, author]) Line::spaced([alias, author])
@ -283,6 +301,7 @@ impl<'a> Author<'a> {
/// HTML-related formatting. /// HTML-related formatting.
pub mod html { pub mod html {
/// Comment a string with HTML comments. /// Comment a string with HTML comments.
#[must_use]
pub fn commented(s: &str) -> String { pub fn commented(s: &str) -> String {
format!("<!--\n{s}\n-->") format!("<!--\n{s}\n-->")
} }
@ -290,6 +309,7 @@ pub mod html {
/// Remove html style comments from a string. /// Remove html style comments from a string.
/// ///
/// The HTML comments must start at the beginning of a line and stop at the end. /// The HTML comments must start at the beginning of a line and stop at the end.
#[must_use]
pub fn strip_comments(s: &str) -> String { pub fn strip_comments(s: &str) -> String {
let ends_with_newline = s.ends_with('\n'); let ends_with_newline = s.ends_with('\n');
let mut is_comment = false; let mut is_comment = false;
@ -323,6 +343,7 @@ pub mod issue {
use radicle::issue::{CloseReason, State}; use radicle::issue::{CloseReason, State};
/// Format issue state. /// Format issue state.
#[must_use]
pub fn state(s: &State) -> term::Paint<String> { pub fn state(s: &State) -> term::Paint<String> {
match s { match s {
State::Open => term::format::positive(s.to_string()), State::Open => term::format::positive(s.to_string()),
@ -341,6 +362,7 @@ pub mod patch {
use super::*; use super::*;
use radicle::patch::{State, Verdict}; use radicle::patch::{State, Verdict};
#[must_use]
pub fn verdict(v: Option<Verdict>) -> term::Paint<String> { pub fn verdict(v: Option<Verdict>) -> term::Paint<String> {
match v { match v {
Some(Verdict::Accept) => term::PREFIX_SUCCESS.into(), Some(Verdict::Accept) => term::PREFIX_SUCCESS.into(),
@ -350,6 +372,7 @@ pub mod patch {
} }
/// Format patch state. /// Format patch state.
#[must_use]
pub fn state(s: &State) -> term::Paint<String> { pub fn state(s: &State) -> term::Paint<String> {
match s { match s {
State::Draft => term::format::dim(s.to_string()), State::Draft => term::format::dim(s.to_string()),
@ -366,6 +389,7 @@ pub mod identity {
use radicle::cob::identity::State; use radicle::cob::identity::State;
/// Format identity revision state. /// Format identity revision state.
#[must_use]
pub fn state(s: &State) -> term::Paint<String> { pub fn state(s: &State) -> term::Paint<String> {
match s { match s {
State::Active => term::format::tertiary(s.to_string()), State::Active => term::format::tertiary(s.to_string()),

View File

@ -59,6 +59,7 @@ impl Default for Theme {
impl Theme { impl Theme {
/// Get the named color. /// Get the named color.
#[must_use]
pub fn color(&self, color: &'static str) -> term::Color { pub fn color(&self, color: &'static str) -> term::Color {
if let Some(c) = (self.color)(color) { if let Some(c) = (self.color)(color) {
c c
@ -68,6 +69,7 @@ impl Theme {
} }
/// Return the color of a syntax group. /// Return the color of a syntax group.
#[must_use]
pub fn highlight(&self, group: &'static str) -> Option<term::Color> { pub fn highlight(&self, group: &'static str) -> Option<term::Color> {
let color = match group { let color = match group {
"keyword" => self.color("red"), "keyword" => self.color("red"),

View File

@ -21,6 +21,7 @@ pub struct PassphraseValidator {
impl PassphraseValidator { impl PassphraseValidator {
/// Create a new validator. /// Create a new validator.
#[must_use]
pub fn new(keystore: Keystore) -> Self { pub fn new(keystore: Keystore) -> Self {
Self { keystore } Self { keystore }
} }

View File

@ -140,6 +140,7 @@ blank is also okay.
/// Combine the title and description fields to display to the user. /// Combine the title and description fields to display to the user.
#[inline] #[inline]
#[must_use]
pub fn message(title: &str, description: &str) -> String { pub fn message(title: &str, description: &str) -> String {
format!("{title}\n\n{description}").trim().to_string() format!("{title}\n\n{description}").trim().to_string()
} }

View File

@ -22,6 +22,7 @@ impl Default for UploadPack {
impl UploadPack { impl UploadPack {
/// Construct an empty set of spinners. /// Construct an empty set of spinners.
#[must_use]
pub fn new() -> Self { pub fn new() -> Self {
Self { Self {
remotes: BTreeSet::new(), remotes: BTreeSet::new(),

View File

@ -47,6 +47,7 @@ impl RepoId {
/// ///
/// Eg. `rad:z3XncAdkZjeK9mQS5Sdc4qhw98BUX`. /// Eg. `rad:z3XncAdkZjeK9mQS5Sdc4qhw98BUX`.
/// ///
#[must_use]
pub fn urn(&self) -> String { pub fn urn(&self) -> String {
RAD_PREFIX.to_string() + &self.canonical() RAD_PREFIX.to_string() + &self.canonical()
} }
@ -65,6 +66,7 @@ impl RepoId {
/// ///
/// Eg. `z3XncAdkZjeK9mQS5Sdc4qhw98BUX`. /// Eg. `z3XncAdkZjeK9mQS5Sdc4qhw98BUX`.
/// ///
#[must_use]
pub fn canonical(&self) -> String { pub fn canonical(&self) -> String {
multibase::encode(multibase::Base::Base58Btc, AsRef::<[u8]>::as_ref(&self.0)) multibase::encode(multibase::Base::Base58Btc, AsRef::<[u8]>::as_ref(&self.0))
} }

View File

@ -50,6 +50,7 @@ impl LocalTime {
} }
/// Construct a local time from whole seconds since Epoch. /// Construct a local time from whole seconds since Epoch.
#[must_use]
pub const fn from_secs(secs: u64) -> Self { pub const fn from_secs(secs: u64) -> Self {
Self { Self {
millis: secs as u128 * 1000, millis: secs as u128 * 1000,
@ -57,16 +58,19 @@ impl LocalTime {
} }
/// Construct a local time from milliseconds since Epoch. /// Construct a local time from milliseconds since Epoch.
#[must_use]
pub const fn from_millis(millis: u128) -> Self { pub const fn from_millis(millis: u128) -> Self {
Self { millis } Self { millis }
} }
/// Return whole seconds since Epoch. /// Return whole seconds since Epoch.
#[must_use]
pub fn as_secs(&self) -> u64 { pub fn as_secs(&self) -> u64 {
(self.millis / 1000).try_into().unwrap() (self.millis / 1000).try_into().unwrap()
} }
/// Return milliseconds since Epoch. /// Return milliseconds since Epoch.
#[must_use]
pub fn as_millis(&self) -> u64 { pub fn as_millis(&self) -> u64 {
self.millis.try_into().unwrap() self.millis.try_into().unwrap()
} }
@ -76,6 +80,7 @@ impl LocalTime {
/// # Panics /// # Panics
/// ///
/// This function will panic if `earlier` is later than `self`. /// This function will panic if `earlier` is later than `self`.
#[must_use]
pub fn duration_since(&self, earlier: LocalTime) -> LocalDuration { pub fn duration_since(&self, earlier: LocalTime) -> LocalDuration {
LocalDuration::from_millis( LocalDuration::from_millis(
self.millis self.millis
@ -85,6 +90,7 @@ impl LocalTime {
} }
/// Get the difference between two times. /// Get the difference between two times.
#[must_use]
pub fn diff(&self, other: LocalTime) -> LocalDuration { pub fn diff(&self, other: LocalTime) -> LocalDuration {
if self > &other { if self > &other {
self.duration_since(other) self.duration_since(other)
@ -149,31 +155,37 @@ impl LocalDuration {
pub const MAX: LocalDuration = LocalDuration(u128::MAX); pub const MAX: LocalDuration = LocalDuration(u128::MAX);
/// Create a new duration from whole seconds. /// Create a new duration from whole seconds.
#[must_use]
pub const fn from_secs(secs: u64) -> Self { pub const fn from_secs(secs: u64) -> Self {
Self(secs as u128 * 1000) Self(secs as u128 * 1000)
} }
/// Create a new duration from whole minutes. /// Create a new duration from whole minutes.
#[must_use]
pub const fn from_mins(mins: u64) -> Self { pub const fn from_mins(mins: u64) -> Self {
Self::from_secs(mins * 60) Self::from_secs(mins * 60)
} }
/// Construct a new duration from milliseconds. /// Construct a new duration from milliseconds.
#[must_use]
pub const fn from_millis(millis: u128) -> Self { pub const fn from_millis(millis: u128) -> Self {
Self(millis) Self(millis)
} }
/// Return the number of minutes in this duration. /// Return the number of minutes in this duration.
#[must_use]
pub const fn as_mins(&self) -> u64 { pub const fn as_mins(&self) -> u64 {
self.as_secs() / 60 self.as_secs() / 60
} }
/// Return the number of seconds in this duration. /// Return the number of seconds in this duration.
#[must_use]
pub const fn as_secs(&self) -> u64 { pub const fn as_secs(&self) -> u64 {
(self.0 / 1000) as u64 (self.0 / 1000) as u64
} }
/// Return the number of milliseconds in this duration. /// Return the number of milliseconds in this duration.
#[must_use]
pub const fn as_millis(&self) -> u128 { pub const fn as_millis(&self) -> u128 {
self.0 self.0
} }