radicle_cli/commands/
unfollow.rs1use std::ffi::OsString;
2
3use anyhow::anyhow;
4
5use radicle::node::{Handle, NodeId};
6
7use crate::terminal as term;
8use crate::terminal::args::{Args, Error, Help};
9
10pub const HELP: Help = Help {
11 name: "unfollow",
12 description: "Unfollow a peer",
13 version: env!("RADICLE_VERSION"),
14 usage: r#"
15Usage
16
17 rad unfollow <nid> [<option>...]
18
19 The `unfollow` command takes a Node ID (<nid>), optionally in DID format,
20 and removes the follow policy for that peer.
21
22Options
23
24 --verbose, -v Verbose output
25 --help Print help
26"#,
27};
28
29#[derive(Debug)]
30pub struct Options {
31 pub nid: NodeId,
32 pub verbose: bool,
33}
34
35impl Args for Options {
36 fn from_args(args: Vec<OsString>) -> anyhow::Result<(Self, Vec<OsString>)> {
37 use lexopt::prelude::*;
38
39 let mut parser = lexopt::Parser::from_args(args);
40 let mut nid: Option<NodeId> = None;
41 let mut verbose = false;
42
43 while let Some(arg) = parser.next()? {
44 match &arg {
45 Value(val) if nid.is_none() => {
46 if let Ok(did) = term::args::did(val) {
47 nid = Some(did.into());
48 } else if let Ok(val) = term::args::nid(val) {
49 nid = Some(val);
50 } else {
51 anyhow::bail!("invalid Node ID `{}` specified", val.to_string_lossy());
52 }
53 }
54 Long("verbose") | Short('v') => verbose = true,
55 Long("help") | Short('h') => {
56 return Err(Error::Help.into());
57 }
58 _ => {
59 return Err(anyhow!(arg.unexpected()));
60 }
61 }
62 }
63
64 Ok((
65 Options {
66 nid: nid.ok_or_else(|| anyhow!("a Node ID must be specified"))?,
67 verbose,
68 },
69 vec![],
70 ))
71 }
72}
73
74pub fn run(options: Options, ctx: impl term::Context) -> anyhow::Result<()> {
75 let profile = ctx.profile()?;
76 let mut node = radicle::Node::new(profile.socket());
77 let nid = options.nid;
78
79 let unfollowed = match node.unfollow(nid) {
80 Ok(updated) => updated,
81 Err(e) if e.is_connection_err() => {
82 let mut config = profile.policies_mut()?;
83 config.unfollow(&nid)?
84 }
85 Err(e) => return Err(e.into()),
86 };
87 if unfollowed {
88 term::success!("Follow policy for {} removed", term::format::tertiary(nid),);
89 }
90 Ok(())
91}