Skip to main content

neumann_shell/
cli.rs

1// SPDX-License-Identifier: MIT OR Apache-2.0
2// Command-line argument parsing for Neumann shell.
3
4use clap::{Parser, ValueEnum};
5#[allow(unused_imports)]
6use std::path::PathBuf;
7
8/// Neumann: Unified tensor database for relational, graph, and vector data.
9#[derive(Parser, Debug)]
10#[command(name = "neumann")]
11#[command(author, version, about, long_about = None)]
12#[command(propagate_version = true)]
13pub struct Cli {
14    /// Execute a single query and exit
15    #[arg(short = 'c', long = "command")]
16    pub command: Option<String>,
17
18    /// Execute queries from file
19    #[arg(short = 'f', long = "file")]
20    pub file: Option<PathBuf>,
21
22    /// Output format for non-interactive mode
23    #[arg(short = 'o', long = "output", value_enum, default_value_t = OutputFormat::Table)]
24    pub output_format: OutputFormat,
25
26    /// Disable colored output
27    #[arg(long = "no-color")]
28    pub no_color: bool,
29
30    /// Skip boot sequence animation
31    #[arg(long = "no-boot")]
32    pub no_boot: bool,
33
34    /// Quiet mode: suppress non-essential output
35    #[arg(short = 'q', long = "quiet")]
36    pub quiet: bool,
37}
38
39/// Output format for non-interactive query results.
40#[derive(Debug, Clone, Copy, ValueEnum, Default, PartialEq, Eq)]
41pub enum OutputFormat {
42    /// Human-readable table format (default)
43    #[default]
44    Table,
45    /// JSON format
46    Json,
47    /// CSV format
48    Csv,
49}
50
51#[cfg(test)]
52mod tests {
53    use super::*;
54    use clap::CommandFactory;
55
56    #[test]
57    fn test_cli_verify() {
58        Cli::command().debug_assert();
59    }
60
61    #[test]
62    fn test_cli_default() {
63        let cli = Cli::parse_from(["neumann"]);
64        assert!(cli.command.is_none());
65        assert!(cli.file.is_none());
66        assert_eq!(cli.output_format, OutputFormat::Table);
67        assert!(!cli.no_color);
68        assert!(!cli.no_boot);
69        assert!(!cli.quiet);
70    }
71
72    #[test]
73    fn test_cli_command() {
74        let cli = Cli::parse_from(["neumann", "-c", "SELECT 1"]);
75        assert_eq!(cli.command, Some("SELECT 1".to_string()));
76    }
77
78    #[test]
79    fn test_cli_file() {
80        let cli = Cli::parse_from(["neumann", "-f", "queries.sql"]);
81        assert_eq!(cli.file, Some(PathBuf::from("queries.sql")));
82    }
83
84    #[test]
85    fn test_cli_output_format() {
86        let cli = Cli::parse_from(["neumann", "-o", "json", "-c", "SELECT 1"]);
87        assert_eq!(cli.output_format, OutputFormat::Json);
88
89        let cli = Cli::parse_from(["neumann", "--output", "csv", "-c", "SELECT 1"]);
90        assert_eq!(cli.output_format, OutputFormat::Csv);
91    }
92
93    #[test]
94    fn test_cli_flags() {
95        let cli = Cli::parse_from(["neumann", "--no-color", "--no-boot", "-q"]);
96        assert!(cli.no_color);
97        assert!(cli.no_boot);
98        assert!(cli.quiet);
99    }
100}