pub mod commands;
pub mod tui;
use clap::{Args, Parser, Subcommand};
use std::path::PathBuf;
#[derive(Parser, Debug)]
#[command(
name = "lanflare",
version,
about = "Fast, cross-platform local network file sharing (LocalSend v2.2 compatible)"
)]
pub struct Cli {
#[arg(long, global = true)]
pub alias: Option<String>,
#[arg(long, short, global = true)]
pub port: Option<u16>,
#[command(subcommand)]
pub command: Option<Commands>,
}
#[derive(Subcommand, Debug)]
pub enum Commands {
Scan(ScanArgs),
Send(SendArgs),
Receive(ReceiveArgs),
Status,
}
#[derive(Args, Debug)]
pub struct ScanArgs {
#[arg(long, short = 't', default_value = "3")]
pub duration: u64,
#[arg(long)]
pub no_multicast: bool,
#[arg(long)]
pub no_mdns: bool,
#[arg(long, short = 's')]
pub subnet: bool,
#[arg(long)]
pub no_subnet: bool,
}
#[derive(Args, Debug)]
pub struct SendArgs {
#[arg(required = true)]
pub files: Vec<PathBuf>,
#[arg(long, short)]
pub to: Option<String>,
#[arg(long)]
pub pin: Option<String>,
}
#[derive(Args, Debug)]
pub struct ReceiveArgs {
#[arg(long, short)]
pub dir: Option<PathBuf>,
#[arg(long, short)]
pub port: Option<u16>,
#[arg(long)]
pub auto_accept: bool,
#[arg(long)]
pub pin: Option<String>,
}
pub async fn run() -> anyhow::Result<()> {
let cli = Cli::parse();
let mut config = lanflare_core::config::AppConfig::default();
if let Some(alias) = cli.alias {
config.alias = alias;
}
if let Some(port) = cli.port {
config.port = port;
}
let identity = lanflare_core::crypto::cert::generate_self_signed()?;
match cli.command {
Some(Commands::Scan(args)) => {
let scan_opts = commands::ScanOptions {
duration_secs: args.duration,
multicast: !args.no_multicast,
mdns: !args.no_mdns,
subnet: args.subnet,
fallback_subnet: !args.no_subnet,
};
commands::scan(&config, &identity, &scan_opts).await?;
}
Some(Commands::Send(args)) => {
let send_opts = commands::SendOptions {
files: args.files,
to: args.to,
pin: args.pin,
};
commands::send(&config, &identity, &send_opts).await?;
}
Some(Commands::Receive(args)) => {
let receive_opts = commands::ReceiveOptions {
dir: args.dir,
port: args.port,
auto_accept: args.auto_accept,
pin: args.pin,
};
commands::receive(&config, &identity, &receive_opts).await?;
}
Some(Commands::Status) | None => {
commands::status(&config, &identity).await?;
}
}
Ok(())
}