use clap::Parser;
use clap::Subcommand;
use serde_json::json;
use std::error::Error;
use rubblets::PrintFormattingStringsArgs;
use rubblets::RubbleResult;
#[cfg(feature = "device")]
use rubblets::device;
#[cfg(feature = "ip")]
use rubblets::ip;
#[cfg(feature = "mail")]
use rubblets::mail;
#[cfg(feature = "mpris")]
use rubblets::mpris;
#[cfg(feature = "network")]
use rubblets::network;
#[cfg(feature = "razor")]
use rubblets::razor;
#[cfg(feature = "weather")]
use rubblets::weather;
#[cfg(feature = "wireguard")]
use rubblets::wireguard;
#[derive(Parser)]
#[clap(author, version, about, arg_required_else_help = true)]
struct RubbleArgs {
#[command(subcommand)]
command: Option<Commands>,
user_format: Option<String>,
}
#[derive(Subcommand)]
enum Commands {
#[cfg(feature = "ip")]
IP,
#[cfg(feature = "mail")]
Mail(mail::MailArgs),
#[cfg(feature = "mpris")]
Mpris,
#[cfg(feature = "network")]
Network(network::NetworkArgs),
#[cfg(feature = "razor")]
Razor,
#[cfg(feature = "device")]
Device(device::DeviceArgs),
#[cfg(feature = "weather")]
Weather(weather::WeatherArgs),
#[cfg(feature = "wireguard")]
Wireguard,
ListFormattingStrings(PrintFormattingStringsArgs),
}
impl Commands {
fn formatting_strings(self) -> &'static str {
match self {
#[cfg(feature = "ip")]
Commands::IP => ip::formatting_strings(),
#[cfg(feature = "mail")]
Commands::Mail(_) => mail::formatting_strings(),
#[cfg(feature = "mpris")]
Commands::Mpris => mpris::formatting_strings(),
#[cfg(feature = "network")]
Commands::Network(_) => network::formatting_strings(),
#[cfg(feature = "razor")]
Commands::Razor => razor::formatting_strings(),
#[cfg(feature = "device")]
Commands::Device(args) => args.selector.formatting_strings(),
#[cfg(feature = "weather")]
Commands::Weather(_) => weather::formatting_strings(),
#[cfg(feature = "wireguard")]
Commands::Wireguard => wireguard::formatting_strings(),
Commands::ListFormattingStrings(_) => "",
}
}
fn from_str(
input: &str,
select: Option<device::SystemStats>,
) -> Result<Commands, Box<dyn Error>> {
match input {
#[cfg(feature = "ip")]
"ip" => Ok(Commands::IP),
#[cfg(feature = "mail")]
"mail" => Ok(Commands::Mail(mail::MailArgs::empty())),
#[cfg(feature = "mpris")]
"mpris" => Ok(Commands::Mpris),
#[cfg(feature = "network")]
"network" => Ok(Commands::Network(network::NetworkArgs::empty())),
#[cfg(feature = "razor")]
"razor" => Ok(Commands::Razor),
#[cfg(feature = "device")]
"device" => Ok(Commands::Device(device::DeviceArgs {
selector: select.unwrap(),
})),
#[cfg(feature = "weather")]
"weather" => Ok(Commands::Weather(weather::WeatherArgs::empty())),
#[cfg(feature = "wireguard")]
"wireguard" => Ok(Commands::Wireguard),
_ => panic!("No matching Command"),
}
}
}
fn print_formatting_strings(args: &PrintFormattingStringsArgs) -> RubbleResult {
let available = Commands::from_str(args.command.as_str(), args.selector)
.unwrap()
.formatting_strings();
let formatted = rubblets::format_formatting_strings(available);
return RubbleResult::new(
Ok(json!({ "available": formatted })),
"{{available}}"
)
}
#[tokio::main]
async fn main() {
let args = RubbleArgs::parse();
let mut rubble_result = match args.command {
#[cfg(feature = "ip")]
Some(Commands::IP) => ip::print_ip(),
#[cfg(feature = "mail")]
Some(Commands::Mail(mailargs)) => mail::count(&mailargs),
#[cfg(feature = "mpris")]
Some(Commands::Mpris) => mpris::currently_playing(),
#[cfg(feature = "network")]
Some(Commands::Network(networkargs)) => network::check_status(&networkargs),
#[cfg(feature = "razor")]
Some(Commands::Razor) => razor::mouse_battery_level(),
#[cfg(feature = "device")]
Some(Commands::Device(deviceargs)) => device::SystemStats::to_result(&deviceargs.selector),
#[cfg(feature = "weather")]
Some(Commands::Weather(weatherargs)) => weather::weather_json(&weatherargs).await,
#[cfg(feature = "wireguard")]
Some(Commands::Wireguard) => wireguard::wg_status(),
Some(Commands::ListFormattingStrings(printargs)) => print_formatting_strings(&printargs),
None => panic!("wtf"),
};
rubble_result.user_format = args.user_format;
rubble_result.print()
}