use clap::{Args, Parser, Subcommand};
use log::LevelFilter;
use std::{net::SocketAddr, path::PathBuf};
use crate::app::encrypt::Secret;
#[derive(Parser, Clone, Debug)]
#[command(version, about, long_about = None, name = "tappi-share")]
pub struct Cli {
#[arg(short = 'l', long, default_value = "off")]
pub log_level: LevelFilter,
#[arg(short = 'f', long, default_value = "tappi-share.log")]
pub log_file: String,
#[command(subcommand)]
pub app_mode: Commands,
}
#[allow(clippy::large_enum_variant)]
#[derive(Subcommand, Clone, Debug)]
pub enum Commands {
Client(ClientArgs),
Server(ServerArgs),
}
#[derive(Args, Clone, Debug)]
pub struct ClientArgs {
#[arg(short='f', long, num_args = 1.., value_terminator(";"))]
pub files: Option<Vec<PathBuf>>,
#[arg(short='s', long, default_value = "64", value_parser = parse_kib)]
pub chunk_size: usize,
#[arg(short = 'i', long, default_value = "false")]
pub ignore_empty: bool,
#[arg(short='a', long, num_args = 1.., value_terminator(";"))]
pub additional_servers: Option<Vec<String>>,
#[arg(short = 'u', long)]
pub username: Option<String>,
#[arg(short = 'c', long)]
pub credential: Option<String>,
#[command(subcommand)]
pub signaling_mode: SignalingSolutions,
}
#[derive(Args, Clone, Debug)]
pub struct ServerArgs {
#[arg(short = 'a', long, default_value = "127.0.0.1:3030")]
pub address: SocketAddr,
}
#[derive(Subcommand, Clone, Debug)]
pub enum SignalingSolutions {
Manual(SignalingSolutionManualArgs),
Socket(SignalingSolutionSocketArgs),
Mqtt(SignalingSolutionMqttArgs),
}
#[derive(Args, Clone, Debug)]
pub struct SignalingSolutionManualArgs {
#[arg(short = 'p', long, default_value = "false")]
pub polite: bool, #[arg(short = 's', long)]
pub secret: Option<Secret>,
}
#[derive(Args, Clone, Debug)]
pub struct SignalingSolutionSocketArgs {
#[arg(short = 'a', long, default_value = "127.0.0.1")]
pub address: String,
#[arg(short = 'p', long, default_value = "3030")]
pub port: u16,
#[arg(short = 'r', long)]
pub room: String,
}
#[derive(Args, Clone, Debug)]
pub struct SignalingSolutionMqttArgs {
#[arg(short = 'b', long, default_value = "broker.emqx.io")]
pub broker: String,
#[arg(short = 'p', long, default_value = "1883")]
pub port: u16,
#[arg(short = 't', long, default_value = "inbox")]
pub topic: String,
#[arg(short = 'l', long)]
pub local_name: String,
#[arg(short = 'r', long)]
pub remote_name: String,
#[arg(short = 's', long)]
pub secret: Option<Secret>,
#[arg(short = 'k', long, default_value = "5")]
pub keep_alive: u16,
}
impl SignalingSolutionMqttArgs {
pub fn local_topic(&self) -> String {
format!("{}/{}", self.local_name, self.topic)
}
pub fn remote_topic(&self) -> String {
format!("{}/{}", self.remote_name, self.topic)
}
}
fn parse_kib(s: &str) -> Result<usize, String> {
let kib: u64 = s
.parse()
.map_err(|_| "Expected an integer KiB value".to_string())?;
let bytes = kib * 1024; let result = bytes.clamp(8_192, 65_535) as usize; Ok(result)
}