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 crate::terminal as term;
|
||||||
|
|
||||||
use args::Target;
|
use term::args::BlockTarget;
|
||||||
|
|
||||||
pub use args::Args;
|
pub use args::Args;
|
||||||
pub(crate) use args::ABOUT;
|
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 mut policies = profile.policies_mut()?;
|
||||||
|
|
||||||
let updated = match args.target {
|
let updated = match args.target {
|
||||||
Target::Node(nid) => policies.set_follow_policy(&nid, Policy::Block)?,
|
BlockTarget::Node(nid) => policies.set_follow_policy(&nid, Policy::Block)?,
|
||||||
Target::Repo(rid) => policies.set_seed_policy(&rid, Policy::Block)?,
|
BlockTarget::Repo(rid) => policies.set_seed_policy(&rid, Policy::Block)?,
|
||||||
};
|
};
|
||||||
if updated {
|
if updated {
|
||||||
term::success!("Policy for {} set to 'block'", args.target);
|
term::success!("Policy for {} set to 'block'", args.target);
|
||||||
|
|
|
||||||
|
|
@ -1,44 +1,9 @@
|
||||||
use clap::Parser;
|
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";
|
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)]
|
#[derive(Parser, Debug)]
|
||||||
#[command(about = ABOUT, disable_version_flag = true)]
|
#[command(about = ABOUT, disable_version_flag = true)]
|
||||||
pub struct Args {
|
pub struct Args {
|
||||||
|
|
@ -46,7 +11,7 @@ pub struct Args {
|
||||||
///
|
///
|
||||||
/// [example values: rad:z3Tr6bC7ctEg2EHmLvknUr29mEDLH, z6MkiswaKJ85vafhffCGBu2gdBsYoDAyHVBWRxL3j297fwS9]
|
/// [example values: rad:z3Tr6bC7ctEg2EHmLvknUr29mEDLH, z6MkiswaKJ85vafhffCGBu2gdBsYoDAyHVBWRxL3j297fwS9]
|
||||||
#[arg(value_name = "RID|NID")]
|
#[arg(value_name = "RID|NID")]
|
||||||
pub(super) target: Target,
|
pub(super) target: BlockTarget,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,8 @@ use std::str::FromStr;
|
||||||
use std::time;
|
use std::time;
|
||||||
|
|
||||||
use anyhow::anyhow;
|
use anyhow::anyhow;
|
||||||
|
|
||||||
use clap::builder::TypedValueParser;
|
use clap::builder::TypedValueParser;
|
||||||
|
use thiserror::Error;
|
||||||
|
|
||||||
use radicle::cob::{self, issue, patch};
|
use radicle::cob::{self, issue, patch};
|
||||||
use radicle::crypto;
|
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))
|
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)]
|
#[derive(Clone, Debug)]
|
||||||
pub(crate) struct ScopeParser;
|
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