Skip to main content

zainodlib/
cli.rs

1//! Command-line interface for Zaino.
2
3use std::path::PathBuf;
4
5use clap::{Parser, Subcommand};
6use zaino_common::xdg::resolve_path_with_xdg_config_defaults;
7
8/// Returns the default config path following XDG Base Directory spec.
9///
10/// Uses `$XDG_CONFIG_HOME/zaino/zainod.toml` if set,
11/// otherwise falls back to `$HOME/.config/zaino/zainod.toml`,
12/// or `/tmp/zaino/.config/zaino/zainod.toml` if HOME is unset.
13pub fn default_config_path() -> PathBuf {
14    resolve_path_with_xdg_config_defaults("zaino/zainod.toml")
15}
16
17/// The Zcash Indexing Service.
18#[derive(Parser, Debug)]
19#[command(
20    name = "zainod",
21    version,
22    about = "Zaino - The Zcash Indexing Service",
23    long_about = None
24)]
25pub struct Cli {
26    /// Subcommand to execute.
27    #[command(subcommand)]
28    pub command: Command,
29}
30
31/// Available subcommands.
32#[derive(Subcommand, Debug, Clone)]
33pub enum Command {
34    /// Start the Zaino indexer service.
35    Start {
36        /// Path to the configuration file. Defaults to $XDG_CONFIG_HOME/zaino/zainod.toml
37        #[arg(short, long, value_name = "FILE")]
38        config: Option<PathBuf>,
39    },
40    /// Generate a configuration file with default values.
41    GenerateConfig {
42        /// Output path for the generated config file. Defaults to $XDG_CONFIG_HOME/zaino/zainod.toml
43        #[arg(short, long, value_name = "FILE")]
44        output: Option<PathBuf>,
45    },
46}
47
48impl Command {
49    /// Generate a configuration file with default values.
50    pub fn generate_config(output: Option<PathBuf>) {
51        let path = output.unwrap_or_else(default_config_path);
52
53        let content = match crate::config::generate_default_config() {
54            Ok(content) => content,
55            Err(e) => {
56                eprintln!("Error generating config: {}", e);
57                std::process::exit(1);
58            }
59        };
60
61        // Create parent directories if needed
62        if let Some(parent) = path.parent() {
63            if !parent.exists() {
64                if let Err(e) = std::fs::create_dir_all(parent) {
65                    eprintln!("Error creating directory {}: {}", parent.display(), e);
66                    std::process::exit(1);
67                }
68            }
69        }
70
71        if let Err(e) = std::fs::write(&path, &content) {
72            eprintln!("Error writing to {}: {}", path.display(), e);
73            std::process::exit(1);
74        }
75
76        eprintln!("Generated config file: {}", path.display());
77    }
78}