1use clap::{Parser, Subcommand};
2use std::path::PathBuf;
3
4#[derive(Parser)]
5#[command(name = "server")]
6#[command(about = "GURT Protocol Server")]
7#[command(version = "1.0.0")]
8pub struct Cli {
9 #[command(subcommand)]
10 pub command: Commands,
11}
12
13#[derive(Subcommand)]
14pub enum Commands {
15 Serve(ServeCommand),
16}
17
18#[derive(Parser)]
19pub struct ServeCommand {
20 #[arg(short, long, help = "Configuration file path")]
21 pub config: Option<PathBuf>,
22
23 #[arg(short, long, default_value_t = 4878)]
24 pub port: u16,
25
26 #[arg(long, default_value = "127.0.0.1")]
27 pub host: String,
28
29 #[arg(short, long, default_value = ".")]
30 pub dir: PathBuf,
31
32 #[arg(short, long)]
33 pub verbose: bool,
34
35 #[arg(long, help = "Path to TLS certificate file")]
36 pub cert: Option<PathBuf>,
37
38 #[arg(long, help = "Path to TLS private key file")]
39 pub key: Option<PathBuf>,
40}
41
42impl ServeCommand {
43 pub fn validate(&self) -> crate::Result<()> {
44 if !self.dir.exists() {
45 return Err(crate::ServerError::InvalidPath(
46 format!("Directory does not exist: {}", self.dir.display())
47 ));
48 }
49
50 if !self.dir.is_dir() {
51 return Err(crate::ServerError::InvalidPath(
52 format!("Path is not a directory: {}", self.dir.display())
53 ));
54 }
55
56 match (&self.cert, &self.key) {
57 (Some(cert), Some(key)) => {
58 if !cert.exists() {
59 return Err(crate::ServerError::TlsConfiguration(
60 format!("Certificate file does not exist: {}", cert.display())
61 ));
62 }
63 if !key.exists() {
64 return Err(crate::ServerError::TlsConfiguration(
65 format!("Key file does not exist: {}", key.display())
66 ));
67 }
68 }
69 (Some(_), None) => {
70 return Err(crate::ServerError::TlsConfiguration(
71 "Certificate provided but no key file specified (use --key)".to_string()
72 ));
73 }
74 (None, Some(_)) => {
75 return Err(crate::ServerError::TlsConfiguration(
76 "Key provided but no certificate file specified (use --cert)".to_string()
77 ));
78 }
79 (None, None) => {
80 return Err(crate::ServerError::TlsConfiguration(
81 "GURT protocol requires TLS encryption. Please provide --cert and --key parameters.".to_string()
82 ));
83 }
84 }
85
86 Ok(())
87 }
88}