use std::process::ExitCode;
use clap::{Parser, Subcommand};
#[cfg(feature = "upgrade")]
mod upgrade;
#[derive(Parser)]
#[command(
name = "trojan",
version,
about = "A Rust implementation of the Trojan protocol",
propagate_version = true
)]
struct Cli {
#[command(subcommand)]
command: Commands,
}
#[derive(Subcommand)]
enum Commands {
#[command(name = "server", alias = "serve")]
Server(Box<trojan_server::ServerArgs>),
#[command(name = "client")]
Client(trojan_client::ClientArgs),
#[command(name = "entry")]
Entry(trojan_relay::cli::EntryArgs),
#[command(name = "relay")]
Relay(trojan_relay::cli::RelayArgs),
#[command(name = "auth")]
Auth(trojan_auth::AuthArgs),
#[cfg(feature = "agent")]
#[command(name = "agent")]
Agent(trojan_agent::AgentArgs),
#[cfg(feature = "cert")]
#[command(name = "cert")]
Cert(trojan_cert::CertArgs),
#[cfg(feature = "upgrade")]
#[command(name = "upgrade", alias = "update")]
Upgrade(upgrade::UpgradeArgs),
}
#[tokio::main]
async fn main() -> ExitCode {
rustls::crypto::aws_lc_rs::default_provider()
.install_default()
.expect("failed to install default CryptoProvider");
let cli = Cli::parse();
let result: Result<(), String> = match cli.command {
Commands::Server(args) => trojan_server::cli::run(*args)
.await
.map_err(|e| e.to_string()),
Commands::Client(args) => trojan_client::cli::run(args)
.await
.map_err(|e| e.to_string()),
Commands::Entry(args) => trojan_relay::cli::run_entry(args)
.await
.map_err(|e| e.to_string()),
Commands::Relay(args) => trojan_relay::cli::run_relay(args)
.await
.map_err(|e| e.to_string()),
Commands::Auth(args) => trojan_auth::cli::run(args).await.map_err(|e| e.to_string()),
#[cfg(feature = "agent")]
Commands::Agent(args) => trojan_agent::cli::run(args)
.await
.map_err(|e| e.to_string()),
#[cfg(feature = "cert")]
Commands::Cert(args) => trojan_cert::run(args).map_err(|e| e.to_string()),
#[cfg(feature = "upgrade")]
Commands::Upgrade(args) => upgrade::run(args).await.map_err(|e| e.to_string()),
};
match result {
Ok(()) => ExitCode::SUCCESS,
Err(e) => {
eprintln!("Error: {}", e);
ExitCode::FAILURE
}
}
}