distrans_cli/
cli.rs

1use std::io::IsTerminal;
2
3use clap::{arg, Parser, Subcommand};
4use color_eyre::eyre::{Error, Result};
5use sha2::{Digest, Sha256};
6use tracing::debug;
7
8#[derive(Parser, Debug)]
9#[command(name = "distrans")]
10#[command(bin_name = "distrans")]
11pub struct Cli {
12    #[arg(long, env)]
13    pub no_ui: bool,
14
15    #[arg(long, env)]
16    pub state_dir: Option<String>,
17
18    #[command(subcommand)]
19    pub commands: Commands,
20}
21
22impl Cli {
23    pub fn no_ui(&self) -> bool {
24        return self.no_ui || !std::io::stdout().is_terminal();
25    }
26
27    pub fn state_dir(&self) -> Result<String> {
28        if let Some(s) = &self.state_dir {
29            return Ok(s.to_owned());
30        }
31        match self.commands {
32            Commands::Fetch {
33                ref dht_key,
34                ref root,
35            } => self.state_dir_for(format!("get:{}:{}", dht_key, root)),
36            Commands::Seed { ref file } => self.state_dir_for(format!("seed:{}", file.to_owned())),
37            _ => Err(Error::msg("invalid command")),
38        }
39    }
40
41    pub fn state_dir_for(&self, key: String) -> Result<String> {
42        let mut key_digest = Sha256::new();
43        key_digest.update(&key.as_bytes());
44        let key_digest_bytes: [u8; 32] = key_digest.finalize().into();
45        let dir_name = hex::encode(key_digest_bytes);
46        let data_dir = dirs::state_dir()
47            .or(dirs::data_local_dir())
48            .ok_or(Error::msg("cannot resolve state dir"))?;
49        let state_dir = data_dir
50            .join("distrans")
51            .join(dir_name)
52            .into_os_string()
53            .into_string()
54            .map_err(|os| Error::msg(format!("{:?}", os)))?;
55        debug!(state_dir);
56        Ok(state_dir)
57    }
58
59    pub fn version(&self) -> bool {
60        if let Commands::Version = self.commands {
61            return true;
62        }
63        return false;
64    }
65}
66
67#[derive(Subcommand, Debug)]
68pub enum Commands {
69    Fetch {
70        dht_key: String,
71        #[arg(default_value = ".")]
72        root: String,
73    },
74    Seed {
75        file: String,
76    },
77    Version,
78}