cli: Share common argument types used in `(un)block`
Since `rad block` and `rad unblock` share the same argument type, `BlockTarget` is moved to the exising `terminal/args.rs` module.
This commit is contained in:
parent
cef0ff571d
commit
faf19af9de
|
|
@ -4,7 +4,7 @@ use radicle::node::policy::Policy;
|
|||
|
||||
use crate::terminal as term;
|
||||
|
||||
use args::Target;
|
||||
use term::args::BlockTarget;
|
||||
|
||||
pub use args::Args;
|
||||
pub(crate) use args::ABOUT;
|
||||
|
|
@ -14,8 +14,8 @@ pub fn run(args: Args, ctx: impl term::Context) -> anyhow::Result<()> {
|
|||
let mut policies = profile.policies_mut()?;
|
||||
|
||||
let updated = match args.target {
|
||||
Target::Node(nid) => policies.set_follow_policy(&nid, Policy::Block)?,
|
||||
Target::Repo(rid) => policies.set_seed_policy(&rid, Policy::Block)?,
|
||||
BlockTarget::Node(nid) => policies.set_follow_policy(&nid, Policy::Block)?,
|
||||
BlockTarget::Repo(rid) => policies.set_seed_policy(&rid, Policy::Block)?,
|
||||
};
|
||||
if updated {
|
||||
term::success!("Policy for {} set to 'block'", args.target);
|
||||
|
|
|
|||
|
|
@ -1,44 +1,9 @@
|
|||
use clap::Parser;
|
||||
use thiserror::Error;
|
||||
|
||||
use radicle::prelude::{NodeId, RepoId};
|
||||
use crate::terminal::args::BlockTarget;
|
||||
|
||||
pub(crate) const ABOUT: &str = "Block repositories or nodes from being seeded or followed";
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub(super) enum Target {
|
||||
Node(NodeId),
|
||||
Repo(RepoId),
|
||||
}
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
#[error("invalid repository or node specified (RID parsing failed with: '{repo}', NID parsing failed with: '{node}'))")]
|
||||
pub(super) struct ParseTargetError {
|
||||
repo: radicle::identity::IdError,
|
||||
node: radicle::crypto::PublicKeyError,
|
||||
}
|
||||
|
||||
impl std::str::FromStr for Target {
|
||||
type Err = ParseTargetError;
|
||||
|
||||
fn from_str(val: &str) -> Result<Self, Self::Err> {
|
||||
val.parse::<RepoId>().map(Target::Repo).or_else(|repo| {
|
||||
val.parse::<NodeId>()
|
||||
.map(Target::Node)
|
||||
.map_err(|node| ParseTargetError { repo, node })
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for Target {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
Self::Node(nid) => nid.fmt(f),
|
||||
Self::Repo(rid) => rid.fmt(f),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Parser, Debug)]
|
||||
#[command(about = ABOUT, disable_version_flag = true)]
|
||||
pub struct Args {
|
||||
|
|
@ -46,7 +11,7 @@ pub struct Args {
|
|||
///
|
||||
/// [example values: rad:z3Tr6bC7ctEg2EHmLvknUr29mEDLH, z6MkiswaKJ85vafhffCGBu2gdBsYoDAyHVBWRxL3j297fwS9]
|
||||
#[arg(value_name = "RID|NID")]
|
||||
pub(super) target: Target,
|
||||
pub(super) target: BlockTarget,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
|
|
|||
|
|
@ -4,8 +4,8 @@ use std::str::FromStr;
|
|||
use std::time;
|
||||
|
||||
use anyhow::anyhow;
|
||||
|
||||
use clap::builder::TypedValueParser;
|
||||
use thiserror::Error;
|
||||
|
||||
use radicle::cob::{self, issue, patch};
|
||||
use radicle::crypto;
|
||||
|
|
@ -207,6 +207,43 @@ pub fn cob(val: &OsString) -> anyhow::Result<cob::ObjectId> {
|
|||
cob::ObjectId::from_str(&val).map_err(|_| anyhow!("invalid Object ID '{}'", val))
|
||||
}
|
||||
|
||||
/// Targets used in the `block` and `unblock` commands
|
||||
#[derive(Clone, Debug)]
|
||||
pub(crate) enum BlockTarget {
|
||||
Node(NodeId),
|
||||
Repo(RepoId),
|
||||
}
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
#[error("invalid repository or node specified (RID parsing failed with: '{repo}', NID parsing failed with: '{node}'))")]
|
||||
pub(crate) struct BlockTargetParseError {
|
||||
repo: radicle::identity::IdError,
|
||||
node: radicle::crypto::PublicKeyError,
|
||||
}
|
||||
|
||||
impl std::str::FromStr for BlockTarget {
|
||||
type Err = BlockTargetParseError;
|
||||
|
||||
fn from_str(val: &str) -> Result<Self, Self::Err> {
|
||||
val.parse::<RepoId>()
|
||||
.map(BlockTarget::Repo)
|
||||
.or_else(|repo| {
|
||||
val.parse::<NodeId>()
|
||||
.map(BlockTarget::Node)
|
||||
.map_err(|node| BlockTargetParseError { repo, node })
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for BlockTarget {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
Self::Node(nid) => nid.fmt(f),
|
||||
Self::Repo(rid) => rid.fmt(f),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub(crate) struct ScopeParser;
|
||||
|
||||
|
|
@ -231,3 +268,29 @@ impl TypedValueParser for ScopeParser {
|
|||
))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use std::str::FromStr;
|
||||
|
||||
use super::BlockTarget;
|
||||
use super::BlockTargetParseError;
|
||||
|
||||
#[test]
|
||||
fn should_parse_nid() {
|
||||
let target = BlockTarget::from_str("z6MkiswaKJ85vafhffCGBu2gdBsYoDAyHVBWRxL3j297fwS9");
|
||||
assert!(target.is_ok())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_parse_rid() {
|
||||
let target = BlockTarget::from_str("rad:z3Tr6bC7ctEg2EHmLvknUr29mEDLH");
|
||||
assert!(target.is_ok())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_not_parse() {
|
||||
let err = BlockTarget::from_str("bee").unwrap_err();
|
||||
assert!(matches!(err, BlockTargetParseError { .. }));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue