use clap::{Args, Parser, Subcommand, ValueEnum}; use telnet::Telnet; use crate::parameter::ParameterList; use crate::models::{Channel, EventType}; use crate::models::Client; use crate::utils::SendTextMessageTarget; use crate::wrappers; #[derive(Parser)] #[command(author, version, about, long_about = None)] #[command(propagate_version = true)] struct Cli { #[command(subcommand)] command: Commands, } #[derive(Subcommand)] pub enum Commands { Channels(ChannelsArgs), Clients, Fetch(FetchArgs), Message(MessageArgs), Move(MoveArgs), Update(UpdateArgs), Events(EventArgs), } #[derive(Args)] pub struct ChannelsArgs { #[arg(long)] pub spacers: bool, } #[derive(Args)] pub struct FetchArgs { #[arg(long)] strict_client: bool, #[arg(long)] strict_channel: bool, #[arg(long)] channel: Option, #[arg(long)] client: Option, } #[derive(Args)] pub struct MessageArgs { #[arg(long)] strict_client: bool, #[arg(long)] client: Option, #[arg(long)] server: bool, pub message: String, } #[derive(Args)] pub struct MoveArgs { #[arg(long)] strict_client: bool, #[arg(long)] strict_channel: bool, channel: String, client: Option, } #[derive(Args)] pub struct UpdateArgs { #[arg(long, short)] name: Option, #[arg(long, short)] away: Option, #[arg(long, short)] back: bool, #[arg(long, short)] microphone: Option, #[arg(long, short)] speakers: Option, } #[derive(Clone, ValueEnum)] pub enum EventArgsFilter { All, Mine, Others, } #[derive(Args)] pub struct EventArgs { pub event: Vec, #[arg(long, short)] pub filter: Option, } impl FetchArgs { pub fn want_channel(&self) -> bool { self.channel.is_some() } pub fn want_client(&self) -> bool { self.client.is_some() } pub fn channel(&self, connection: &mut Telnet) -> Result, String> { if let Some(channel) = &self.channel { wrappers::find_channel(connection, "channel_name", channel, self.strict_channel) } else { Err("No channel specified.".to_string()) } } pub fn client(&self, connection: &mut Telnet) -> Result, String> { if let Some(client) = &self.client { wrappers::find_client(connection, "client_nickname", client, self.strict_client) } else { Err("No client specified.".to_string()) } } } impl MessageArgs { pub fn target(&self, connection: &mut Telnet) -> Result { if self.server { Ok(SendTextMessageTarget::Server) } else if let Some(client) = &self.client { if let Some(client) = wrappers::find_client(connection, "client_nickname", client, self.strict_client)? { return Ok(SendTextMessageTarget::Client(client)); } return Err("Could not find client.".to_string()); } else { Ok(SendTextMessageTarget::Channel) } } } impl MoveArgs { pub fn channel(&self, connection: &mut Telnet) -> Result, String> { wrappers::find_channel(connection, "channel_name", &self.channel, self.strict_channel) } pub fn client(&self, connection: &mut Telnet) -> Result, String> { match &self.client { Some(client) => { wrappers::find_client(connection, "client_nickname", client, self.strict_client) } None => { match wrappers::find_self(connection) { Ok(client) => Ok(Some(client)), Err(msg) => Err(msg) } } } } } impl UpdateArgs { pub fn to_parameter_list(&self) -> ParameterList { let mut params: ParameterList = ParameterList::new(); if let Some(name) = &self.name { params.insert(String::from("client_nickname"), name.clone()); } if let Some(away) = &self.away { params.insert(String::from("client_away_message"), away.clone()); params.insert(String::from("client_away"), String::from("1")); } if self.back { params.insert(String::from("client_away"), String::from("0")); } if let Some(microphone) = self.microphone { params.insert(String::from("client_input_muted"), u8::from(!microphone).to_string()); } if let Some(speakers) = self.speakers { params.insert(String::from("client_output_muted"), u8::from(!speakers).to_string()); } params } } pub fn init() -> Commands { Cli::parse().command }