diff --git a/crates/radicle-cli/src/commands/id.rs b/crates/radicle-cli/src/commands/id.rs index 6bc9abbd..3b489c96 100644 --- a/crates/radicle-cli/src/commands/id.rs +++ b/crates/radicle-cli/src/commands/id.rs @@ -135,12 +135,11 @@ pub fn run(args: Args, ctx: impl term::Context) -> anyhow::Result<()> { let proposal = match update::privacy_allow_list(proposal, allow, disallow) { Ok(proposal) => proposal, Err(e) => match e { - update::error::PrivacyAllowList::Overlapping(overlap) => anyhow::bail!("`--allow` and `--disallow` must not overlap: {overlap:?}"), - update::error::PrivacyAllowList::PublicVisibility => return Err(Error::WithHint { - err: + update::error::PrivacyAllowList::Overlapping(overlap) =>anyhow::bail!("`--allow` and `--disallow` must not overlap: {overlap:?}"), + update::error::PrivacyAllowList::PublicVisibility => return Err(Error::with_hint( anyhow!("`--allow` and `--disallow` should only be used for private repositories"), - hint: "use `--visibility private` to make the repository private, or perhaps you meant to use `--delegate`/`--rescind`", - }.into()) + "use `--visibility private` to make the repository private, or perhaps you meant to use `--delegate`/`--rescind`") + .into()) } }; let threshold = proposal.threshold; diff --git a/crates/radicle-cli/src/commands/issue.rs b/crates/radicle-cli/src/commands/issue.rs index 24a28415..79f1cedb 100644 --- a/crates/radicle-cli/src/commands/issue.rs +++ b/crates/radicle-cli/src/commands/issue.rs @@ -122,9 +122,8 @@ pub fn run(args: Args, ctx: impl term::Context) -> anyhow::Result<()> { let id = id.resolve(&repo.backend)?; let issue = issues .get(&id) - .map_err(|e| Error::WithHint { - err: e.into(), - hint: "reset the cache with `rad issue cache` and try again", + .map_err(|e| { + Error::with_hint(e, "reset the cache with `rad issue cache` and try again") })? .context("No issue with the given ID exists")?; term::issue::show(&issue, &id, format, args.verbose, &profile)?; diff --git a/crates/radicle-cli/src/commands/patch/show.rs b/crates/radicle-cli/src/commands/patch/show.rs index 4e3d3dec..e6d0b1c9 100644 --- a/crates/radicle-cli/src/commands/patch/show.rs +++ b/crates/radicle-cli/src/commands/patch/show.rs @@ -33,10 +33,9 @@ pub fn run( workdir: Option<&git::raw::Repository>, ) -> anyhow::Result<()> { let patches = term::cob::patches(profile, stored)?; - let Some(patch) = patches.get(patch_id).map_err(|e| Error::WithHint { - err: e.into(), - hint: "reset the cache with `rad patch cache` and try again", - })? + let Some(patch) = patches + .get(patch_id) + .map_err(|e| Error::with_hint(e, "reset the cache with `rad patch cache` and try again"))? else { anyhow::bail!("Patch `{patch_id}` not found"); }; diff --git a/crates/radicle-cli/src/commands/publish.rs b/crates/radicle-cli/src/commands/publish.rs index e2ac9f10..aca4b5d8 100644 --- a/crates/radicle-cli/src/commands/publish.rs +++ b/crates/radicle-cli/src/commands/publish.rs @@ -25,22 +25,20 @@ pub fn run(args: Args, ctx: impl term::Context) -> anyhow::Result<()> { let doc = identity.doc(); if doc.is_public() { - return Err(term::Error::WithHint { - err: anyhow!("repository is already public"), - hint: "to announce the repository to the network, run `rad sync --inventory`", - } + return Err(term::Error::with_hint( + anyhow!("repository is already public"), + "to announce the repository to the network, run `rad sync --inventory`", + ) .into()); } if !doc.is_delegate(&profile.id().into()) { return Err(anyhow!("only the repository delegate can publish it")); } if doc.delegates().len() > 1 { - return Err(term::Error::WithHint { - err: anyhow!( - "only repositories with a single delegate can be published with this command" - ), - hint: "see `rad id --help` to publish repositories with more than one delegate", - } + return Err(term::Error::with_hint( + anyhow!("only repositories with a single delegate can be published with this command"), + "see `rad id --help` to publish repositories with more than one delegate", + ) .into()); } let signer = profile.signer()?; diff --git a/crates/radicle-cli/src/terminal.rs b/crates/radicle-cli/src/terminal.rs index 6cfbf4f1..90a1dd3c 100644 --- a/crates/radicle-cli/src/terminal.rs +++ b/crates/radicle-cli/src/terminal.rs @@ -45,10 +45,10 @@ impl Context for DefaultContext { fn profile(&self) -> Result { match Profile::load() { Ok(profile) => Ok(profile), - Err(radicle::profile::Error::NotFound(path)) => Err(args::Error::WithHint { - err: anyhow::anyhow!("Radicle profile not found in '{}'.", path.display()), - hint: "To setup your radicle profile, run `rad auth`.", - } + Err(radicle::profile::Error::NotFound(path)) => Err(args::Error::with_hint( + anyhow::anyhow!("Radicle profile not found in '{}'.", path.display()), + "To setup your radicle profile, run `rad auth`.", + ) .into()), Err(radicle::profile::Error::LoadConfig(e)) => Err(e.into()), Err(e) => Err(anyhow::anyhow!("Could not load radicle profile: {e}")), diff --git a/crates/radicle-cli/src/terminal/args.rs b/crates/radicle-cli/src/terminal/args.rs index a2e17575..71553104 100644 --- a/crates/radicle-cli/src/terminal/args.rs +++ b/crates/radicle-cli/src/terminal/args.rs @@ -8,10 +8,20 @@ use radicle::prelude::{Did, NodeId, RepoId}; pub(crate) enum Error { /// An error with a hint. #[error("{err}")] - WithHint { - err: anyhow::Error, - hint: &'static str, - }, + WithHint { err: anyhow::Error, hint: String }, +} + +impl Error { + pub fn with_hint(err: E, hint: H) -> Self + where + E: Into, + H: ToString, + { + Self::WithHint { + err: err.into(), + hint: hint.to_string(), + } + } } /// Targets used in the `block` and `unblock` commands diff --git a/crates/radicle-cli/src/terminal/cob.rs b/crates/radicle-cli/src/terminal/cob.rs index 7086c4c3..f2f2d250 100644 --- a/crates/radicle-cli/src/terminal/cob.rs +++ b/crates/radicle-cli/src/terminal/cob.rs @@ -108,10 +108,7 @@ fn with_hint(e: profile::Error) -> anyhow::Error { #[allow(clippy::wildcard_enum_match_arm)] match e { profile::Error::CobsCache(cob::cache::Error::OutOfDate) => { - anyhow::Error::from(terminal::args::Error::WithHint { - err: e.into(), - hint: MIGRATION_HINT, - }) + terminal::args::Error::with_hint(e, MIGRATION_HINT).into() } e => anyhow::Error::from(e), }