aboutsummaryrefslogtreecommitdiffstats
path: root/mumctl
diff options
context:
space:
mode:
Diffstat (limited to 'mumctl')
-rw-r--r--mumctl/Cargo.toml9
-rw-r--r--mumctl/src/main.rs883
2 files changed, 404 insertions, 488 deletions
diff --git a/mumctl/Cargo.toml b/mumctl/Cargo.toml
index 02326c8..5a12d8f 100644
--- a/mumctl/Cargo.toml
+++ b/mumctl/Cargo.toml
@@ -11,11 +11,12 @@ repository = "https://github.com/sornas/mum"
license = "MIT"
[dependencies]
-mumlib = { version = "0.3", path = "../mumlib" }
+mumlib = { path = "../mumlib" }
-clap = { version = "2.33", features = ["yaml"] }
-colored = "2.0"
+anyhow = "1"
+bincode = "1"
+colored = "2"
log = "0.4"
-bincode = "1.3.2"
+structopt = "0.3"
#cursive = "0.15"
diff --git a/mumctl/src/main.rs b/mumctl/src/main.rs
index a187a3a..95b98f2 100644
--- a/mumctl/src/main.rs
+++ b/mumctl/src/main.rs
@@ -1,10 +1,11 @@
-use clap::{App, AppSettings, Arg, Shell, SubCommand, ArgMatches};
+use anyhow::Result;
use colored::Colorize;
-use log::{Record, Level, Metadata, LevelFilter, error, warn};
-use mumlib::command::{Command, CommandResponse};
-use mumlib::config::{self, ServerConfig, Config};
-use mumlib::state::Channel;
-use std::{io::{self, Read, BufRead, Write}, iter, fmt::{Display, Formatter}, os::unix::net::UnixStream};
+use log::*;
+use mumlib::command::{Command as MumCommand, CommandResponse};
+use mumlib::config::{self, Config, ServerConfig};
+use mumlib::state::Channel as MumChannel;
+use std::{io::{self, Read, BufRead, Write}, iter, fmt::Formatter, os::unix::net::UnixStream};
+use structopt::{clap::Shell, StructOpt};
const INDENTATION: &str = " ";
@@ -41,152 +42,287 @@ impl log::Log for SimpleLogger {
static LOGGER: SimpleLogger = SimpleLogger;
-fn main() {
+#[derive(Debug, StructOpt)]
+struct Mum {
+ #[structopt(subcommand)]
+ command: Command,
+}
+
+#[derive(Debug, StructOpt)]
+enum Command {
+ /// Connect to a server
+ Connect {
+ host: String,
+ username: Option<String>,
+ password: Option<String>,
+ port: Option<u16>,
+ },
+ /// Disconnect from the currently connected server
+ Disconnect,
+ /// Handle servers
+ Server(Server),
+ /// Handle channels in the connected server
+ Channel(Channel),
+ /// Show current status
+ Status,
+ /// Change config values
+ Config {
+ key: String,
+ value: String,
+ },
+ /// Reload the config file
+ ConfigReload,
+ /// Output CLI completions
+ Completions(Completions),
+ /// Change volume of either you or someone else
+ Volume {
+ user: String,
+ volume: Option<f32>,
+ },
+ /// Mute someone/yourself
+ Mute {
+ user: Option<String>,
+ },
+ /// Unmute someone/yourself
+ Unmute {
+ user: Option<String>,
+ },
+ /// Deafen yourself
+ Deafen,
+ /// Undeafen yourself
+ Undeafen,
+}
+
+#[derive(Debug, StructOpt)]
+enum Server {
+ /// Configure a saved server
+ Config {
+ server_name: Option<String>,
+ key: Option<String>,
+ value: Option<String>,
+ },
+ /// Rename a saved server
+ Rename {
+ old_name: String,
+ new_name: String
+ },
+ /// Add a new saved server
+ Add {
+ name: String,
+ host: String,
+ port: Option<u16>,
+ username: Option<String>,
+ password: Option<String>,
+ },
+ /// Remove a saved server
+ Remove {
+ name: String,
+ },
+ /// List saved servers and number of people connected
+ List,
+}
+
+#[derive(Debug, StructOpt)]
+enum Channel {
+ List {
+ #[structopt(short = "s", long = "short")]
+ short: bool,
+ },
+ Connect {
+ name: String,
+ },
+}
+
+#[derive(Debug, StructOpt)]
+enum Completions {
+ Zsh,
+ Bash,
+ Fish,
+}
+
+#[derive(Debug)]
+enum CliError {
+ NoUsername,
+ ConnectionError,
+ NoServerFound(String),
+ NotSet(String),
+ UseServerRename,
+ ConfigKeyNotFound(String),
+ ServerAlreadyExists(String),
+ NoServers,
+}
+
+impl std::error::Error for CliError {}
+
+impl std::fmt::Display for CliError {
+ fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
+ match self {
+ CliError::NoUsername => {
+ write!(f, "No username specified")
+ }
+ CliError::ConnectionError => {
+ write!(f, "Unable to connect to mumd. Is mumd running?")
+ }
+ CliError::NoServerFound(s) => {
+ write!(f, "Server '{}' not found", s)
+ }
+ CliError::NotSet(s) => {
+ write!(f, "Key '{}' not set", s) //TODO
+ }
+ CliError::UseServerRename => {
+ write!(f, "Use 'server rename' instead")
+ }
+ CliError::ConfigKeyNotFound(s) => {
+ write!(f, "Key '{}' not found", s)
+ }
+ CliError::ServerAlreadyExists(s) => {
+ write!(f, "A server named '{}' already exists", s)
+ }
+ CliError::NoServers => {
+ write!(f, "No servers found")
+ }
+ }
+ }
+}
+
+fn main() -> Result<()> {
log::set_logger(&LOGGER)
.map(|()| log::set_max_level(LevelFilter::Info)).unwrap();
- let mut config = match config::read_default_cfg() {
- Ok(c) => c,
- Err(e) => {
- error!("Couldn't read config: {}", e);
- return;
- }
- };
+ let mut config = config::read_default_cfg()?;
- let mut app = App::new("mumctl")
- .setting(AppSettings::ArgRequiredElseHelp)
- .version(env!("VERSION"))
- .subcommand(
- SubCommand::with_name("connect")
- .about("Connect to a server")
- .arg(Arg::with_name("host").required(true))
- .arg(Arg::with_name("username"))
- .arg(Arg::with_name("password"))
- .arg(
- Arg::with_name("port")
- .long("port")
- .short("p")
- .takes_value(true),
- ),
- )
- .subcommand(
- SubCommand::with_name("disconnect")
- .about("Disconnect from the currently connected server"),
- )
- .subcommand(
- SubCommand::with_name("server")
- .setting(AppSettings::ArgRequiredElseHelp)
- .about("Handle servers")
- .subcommand(
- SubCommand::with_name("config")
- .about("Configure a saved server")
- .arg(Arg::with_name("server_name"))
- .arg(Arg::with_name("var_name"))
- .arg(Arg::with_name("var_value")),
- )
- .subcommand(
- SubCommand::with_name("rename")
- .about("Rename a saved server")
- .arg(Arg::with_name("prev_name").required(true))
- .arg(Arg::with_name("next_name").required(true)),
- )
- .subcommand(
- SubCommand::with_name("add")
- .about("Add a new saved server")
- .arg(Arg::with_name("name").required(true))
- .arg(Arg::with_name("host").required(true))
- .arg(
- Arg::with_name("port")
- .long("port")
- .takes_value(true)
- .default_value("64738"),
- )
- .arg(
- Arg::with_name("username")
- .long("username")
- .takes_value(true),
- )
- .arg(
- Arg::with_name("password")
- .long("password")
- .takes_value(true),
- ),
- )
- .subcommand(
- SubCommand::with_name("remove")
- .about("Remove a saved server")
- .arg(Arg::with_name("name").required(true)),
- )
- .subcommand(
- SubCommand::with_name("list")
- .about("List saved servers and number of people connected"),
+ let opt = Mum::from_args();
+ match opt.command {
+ Command::Connect { host, username, password, port } => {
+ let port = port.unwrap_or(mumlib::DEFAULT_PORT);
+
+ let (host, username, password, port) = match config.servers.iter().find(|e| e.name == host) {
+ Some(server) => (
+ &server.host,
+ server.username.as_ref().or(username.as_ref()).ok_or(CliError::NoUsername)?,
+ server.password.as_ref().or(password.as_ref()),
+ server.port.unwrap_or(port),
),
- )
- .subcommand(
- SubCommand::with_name("channel")
- .about("Handle channels in the connected server")
- .setting(AppSettings::ArgRequiredElseHelp)
- .subcommand(
- SubCommand::with_name("list")
- .about("List all channels")
- .arg(Arg::with_name("short").long("short").short("s")),
- )
- .subcommand(
- SubCommand::with_name("connect")
- .about("Connect to another channel")
- .arg(Arg::with_name("channel").required(true)),
+ None => (
+ &host,
+ username.as_ref().ok_or(CliError::NoUsername)?,
+ password.as_ref(),
+ port,
),
- )
- .subcommand(SubCommand::with_name("status").about("Show current status"))
- .subcommand(
- SubCommand::with_name("config")
- .about("Change config values")
- .arg(Arg::with_name("name").required(true))
- .arg(Arg::with_name("value").required(true)),
- )
- .subcommand(
- SubCommand::with_name("config-reload").about("Force a reload of the config file"),
- )
- .subcommand(
- SubCommand::with_name("completions")
- .about("Generate CLI completions")
- .arg(Arg::with_name("zsh").long("zsh"))
- .arg(Arg::with_name("bash").long("bash"))
- .arg(Arg::with_name("fish").long("fish")),
- )
- .subcommand(
- SubCommand::with_name("volume")
- .about("Change volume of either you or someone else")
- .subcommand(
- SubCommand::with_name("set")
- .arg(Arg::with_name("user").required(true))
- .arg(Arg::with_name("volume").required(true)),
- )
- .arg(Arg::with_name("user").required(true))
- .setting(AppSettings::SubcommandsNegateReqs),
- )
- .subcommand(
- SubCommand::with_name("mute")
- .about("Mute someone/yourself")
- .arg(Arg::with_name("user"))
- )
- .subcommand(
- SubCommand::with_name("unmute")
- .about("Unmute someone/yourself")
- .arg(Arg::with_name("user"))
- )
- .subcommand(
- SubCommand::with_name("deafen")
- .about("Deafen yourself")
- )
- .subcommand(
- SubCommand::with_name("undeafen")
- .about("Undeafen yourself")
- );
+ };
- let matches = app.clone().get_matches();
-
- if let Err(e) = process_matches(matches, &mut config, &mut app) {
- error!("{}", e);
+ let response = send_command(MumCommand::ServerConnect {
+ host: host.to_string(),
+ port,
+ username: username.to_string(),
+ password: password.map(|x| x.to_string()),
+ accept_invalid_cert: true //TODO
+ })??;
+ if let Some(CommandResponse::ServerConnect { welcome_message }) = response {
+ println!("Connected to {}", host);
+ if let Some(message) = welcome_message {
+ println!("Welcome: {}", message);
+ }
+ }
+ }
+ Command::Disconnect => {
+ send_command(MumCommand::ServerDisconnect)??;
+ }
+ Command::Server(server_command) => {
+ match_server_command(server_command, &mut config)?;
+ }
+ Command::Channel(channel_command) => {
+ match channel_command {
+ Channel::List { short: _short } => { //TODO actually use this
+ match send_command(MumCommand::ChannelList)?? {
+ Some(CommandResponse::ChannelList { channels }) => {
+ print_channel(&channels, 0);
+ }
+ _ => unreachable!("Response should only be a ChannelList"),
+ }
+ }
+ Channel::Connect { name } => {
+ send_command(MumCommand::ChannelJoin {
+ channel_identifier: name
+ })??;
+ }
+ }
+ }
+ Command::Status => {
+ match send_command(MumCommand::Status)?? {
+ Some(CommandResponse::Status { server_state }) => {
+ parse_state(&server_state);
+ }
+ _ => unreachable!("Response should only be a Status"),
+ }
+ }
+ Command::Config { key, value } => {
+ match key.as_str() {
+ "audio.input_volume" => {
+ if let Ok(volume) = value.parse() {
+ send_command(MumCommand::InputVolumeSet(volume))??;
+ config.audio.input_volume = Some(volume);
+ }
+ }
+ "audio.output_volume" => {
+ if let Ok(volume) = value.parse() {
+ send_command(MumCommand::OutputVolumeSet(volume))??;
+ config.audio.output_volume = Some(volume);
+ }
+ }
+ _ => {
+ return Err(CliError::ConfigKeyNotFound(key))?;
+ }
+ }
+ }
+ Command::ConfigReload => {
+ send_command(MumCommand::ConfigReload)??;
+ }
+ Command::Completions(completions) => {
+ Mum::clap().gen_completions_to(
+ "mumctl",
+ match completions {
+ Completions::Bash => Shell::Bash,
+ Completions::Fish => Shell::Fish,
+ _ => Shell::Zsh,
+ },
+ &mut io::stdout(),
+ );
+ }
+ Command::Volume { user, volume } => {
+ if let Some(volume) = volume {
+ send_command(MumCommand::UserVolumeSet(user, volume))??;
+ } else {
+ //TODO report volume of user
+ // needs work on mumd
+ todo!();
+ }
+ }
+ Command::Mute { user } => {
+ match user {
+ Some(user) => {
+ send_command(MumCommand::MuteOther(user, Some(true)))??;
+ }
+ None => {
+ send_command(MumCommand::MuteSelf(Some(true)))??;
+ }
+ }
+ }
+ Command::Unmute { user } => {
+ match user {
+ Some(user) => {
+ send_command(MumCommand::MuteOther(user, Some(false)))??;
+ }
+ None => {
+ send_command(MumCommand::MuteSelf(Some(false)))??;
+ }
+ }
+ }
+ Command::Deafen => {
+ send_command(MumCommand::DeafenSelf(Some(true)))??;
+ }
+ Command::Undeafen => {
+ send_command(MumCommand::DeafenSelf(Some(false)))??;
+ }
}
if !config::cfg_exists() {
@@ -202,31 +338,123 @@ fn main() {
} else {
error_if_err!(config.write_default_cfg(false));
}
+ Ok(())
}
-fn process_matches(matches: ArgMatches, config: &mut Config, app: &mut App) -> Result<(), Error> {
- if let Some(matches) = matches.subcommand_matches("connect") {
- match_server_connect(matches, &config)?;
- } else if let Some(_) = matches.subcommand_matches("disconnect") {
- error_if_err!(send_command(Command::ServerDisconnect)?);
- } else if let Some(matches) = matches.subcommand_matches("server") {
- if let Some(matches) = matches.subcommand_matches("config") {
- match_server_config(matches, config);
- } else if let Some(matches) = matches.subcommand_matches("rename") {
- match_server_rename(matches, config);
- } else if let Some(matches) = matches.subcommand_matches("remove") {
- match_server_remove(matches, config);
- } else if let Some(matches) = matches.subcommand_matches("add") {
- match_server_add(matches, config);
- } else if let Some(_) = matches.subcommand_matches("list") {
+fn match_server_command(server_command: Server, config: &mut Config) -> Result<()> {
+ match server_command {
+ Server::Config { server_name, key, value } => {
+ let server_name = match server_name {
+ Some(server_name) => server_name,
+ None => {
+ for server in config.servers.iter() {
+ println!("{}", server.name);
+ }
+ return Ok(());
+ }
+ };
+ let server = config.servers
+ .iter_mut()
+ .find(|s| s.name == server_name)
+ .ok_or(CliError::NoServerFound(server_name))?;
+
+ match (key.as_deref(), value) {
+ (None, _) => {
+ print!(
+ "{}{}{}{}",
+ format!("host: {}\n", server.host.to_string()),
+ server
+ .port
+ .map(|s| format!("port: {}\n", s))
+ .unwrap_or_else(|| "".to_string()),
+ server
+ .username
+ .as_ref()
+ .map(|s| format!("username: {}\n", s))
+ .unwrap_or_else(|| "".to_string()),
+ server
+ .password
+ .as_ref()
+ .map(|s| format!("password: {}\n", s))
+ .unwrap_or_else(|| "".to_string()),
+ );
+ }
+ (Some("name"), None) => {
+ println!("{}", server.name);
+ }
+ (Some("host"), None) => {
+ println!("{}", server.host);
+ }
+ (Some("port"), None) => {
+ println!("{}",
+ server
+ .port
+ .ok_or(CliError::NotSet("port".to_string()))?);
+ }
+ (Some("username"), None) => {
+ println!("{}",
+ server
+ .username
+ .as_ref()
+ .ok_or(CliError::NotSet("username".to_string()))?);
+ }
+ (Some("password"), None) => {
+ println!("{}",
+ server
+ .password
+ .as_ref()
+ .ok_or(CliError::NotSet("password".to_string()))?);
+ }
+ (Some("name"), Some(_)) => {
+ return Err(CliError::UseServerRename)?;
+ }
+ (Some("host"), Some(value)) => {
+ server.host = value;
+ }
+ (Some("port"), Some(value)) => {
+ server.port = Some(value.parse().unwrap());
+ }
+ (Some("username"), Some(value)) => {
+ server.username = Some(value);
+ }
+ (Some("password"), Some(value)) => {
+ server.password = Some(value);
+ //TODO ask stdin if empty
+ }
+ (Some(_), _) => {
+ return Err(CliError::ConfigKeyNotFound(key.unwrap()))?;
+ }
+ }
+ }
+ Server::Rename { old_name, new_name } => {
+ config.servers.iter_mut().find(|s| s.name == old_name).ok_or(CliError::NoServerFound(old_name))?.name = new_name;
+ }
+ Server::Add { name, host, port, username, password } => {
+ if config.servers.iter().any(|s| s.name == name) {
+ return Err(CliError::ServerAlreadyExists(name))?;
+ } else {
+ config.servers.push(ServerConfig {
+ name,
+ host,
+ port,
+ username,
+ password,
+ });
+ }
+ }
+ Server::Remove { name } => {
+ let idx = config.servers.iter().position(|s| s.name == name).ok_or(CliError::NoServerFound(name))?;
+ config.servers.remove(idx);
+ }
+ Server::List => {
if config.servers.is_empty() {
- warn!("No servers in config");
+ return Err(CliError::NoServers)?;
}
let query = config
.servers
.iter()
.map(|e| {
- let response = send_command(Command::ServerStatus {
+ let response = send_command(MumCommand::ServerStatus {
host: e.host.clone(),
port: e.port.unwrap_or(mumlib::DEFAULT_PORT),
});
@@ -246,314 +474,12 @@ fn process_matches(matches: ArgMatches, config: &mut Config, app: &mut App) -> R
}
}
}
- } else if let Some(matches) = matches.subcommand_matches("channel") {
- if let Some(_matches) = matches.subcommand_matches("list") {
- match send_command(Command::ChannelList)? {
- Ok(res) => match res {
- Some(CommandResponse::ChannelList { channels }) => {
- print_channel(&channels, 0);
- }
- _ => unreachable!(),
- },
- Err(e) => error!("{}", e),
- }
- } else if let Some(matches) = matches.subcommand_matches("connect") {
- error_if_err!(send_command(Command::ChannelJoin {
- channel_identifier: matches.value_of("channel").unwrap().to_string()
- }));
- }
- } else if let Some(_) = matches.subcommand_matches("status") {
- match send_command(Command::Status)? {
- Ok(res) => match res {
- Some(CommandResponse::Status { server_state }) => {
- parse_status(&server_state);
- }
- _ => unreachable!(),
- },
- Err(e) => error!("{}", e),
- }
- } else if let Some(matches) = matches.subcommand_matches("config") {
- let name = matches.value_of("name").unwrap();
- let value = matches.value_of("value").unwrap();
- match name {
- "audio.input_volume" => {
- if let Ok(volume) = value.parse() {
- error_if_err!(send_command(Command::InputVolumeSet(volume))?);
- config.audio.input_volume = Some(volume);
- }
- }
- "audio.output_volume" => {
- if let Ok(volume) = value.parse() {
- error_if_err!(send_command(Command::OutputVolumeSet(volume))?);
- config.audio.output_volume = Some(volume);
- }
- }
- _ => {
- error!("unknown config value {}", name);
- }
- }
- } else if matches.subcommand_matches("config-reload").is_some() {
- error_if_err!(send_command(Command::ConfigReload)?);
- } else if let Some(matches) = matches.subcommand_matches("completions") {
- app.gen_completions_to(
- "mumctl",
- match matches.value_of("shell").unwrap_or("zsh") {
- "bash" => Shell::Bash,
- "fish" => Shell::Fish,
- _ => Shell::Zsh,
- },
- &mut io::stdout(),
- );
- } else if let Some(matches) = matches.subcommand_matches("volume") {
- if let Some(matches) = matches.subcommand_matches("set") {
- let user = matches.value_of("user").unwrap();
- let volume = matches.value_of("volume").unwrap();
- if let Ok(val) = volume.parse() {
- error_if_err!(send_command(Command::UserVolumeSet(user.to_string(), val)))
- } else {
- error!("invalid volume value: {}", volume);
- }
- } else {
- let _user = matches.value_of("user").unwrap();
- //TODO implement me
- //needs work on mumd to implement
- }
- } else if let Some(matches) = matches.subcommand_matches("mute") {
- let command = if let Some(user) = matches.value_of("user") {
- Command::MuteOther(user.to_string(), Some(true))
- } else {
- Command::MuteSelf(Some(true))
- };
- if let Err(e) = send_command(command)? {
- error!("{}", e);
- }
- } else if let Some(matches) = matches.subcommand_matches("unmute") {
- let command = if let Some(user) = matches.value_of("user") {
- Command::MuteOther(user.to_string(), Some(false))
- } else {
- Command::MuteSelf(Some(false))
- };
- if let Err(e) = send_command(command)? {
- error!("{}", e);
- }
- } else if let Some(_) = matches.subcommand_matches("deafen") {
- if let Err(e) = send_command(Command::DeafenSelf(Some(true)))? {
- error!("{}", e);
- }
- } else if let Some(_) = matches.subcommand_matches("undeafen") {
- if let Err(e) = send_command(Command::DeafenSelf(Some(false)))? {
- error!("{}", e);
- }
- } else {
- unreachable!();
}
-
Ok(())
}
-fn match_server_connect(matches: &clap::ArgMatches<'_>, config: &mumlib::config::Config) -> Result<(), Error> {
- let host = matches.value_of("host").unwrap();
- let username = matches.value_of("username");
- let password = matches.value_of("password");
- let port = match matches.value_of("port").map(|e| e.parse()) {
- None => Some(mumlib::DEFAULT_PORT),
- Some(Err(_)) => None,
- Some(Ok(v)) => Some(v),
- };
- if let Some(port) = port {
- let (host, port, username, password) = match config.servers.iter().find(|e| e.name == host) {
- Some(server_config) => {
- let host = server_config.host.as_str();
- let port = server_config.port.unwrap_or(port);
- let username = server_config
- .username
- .as_deref()
- .or(username);
- if username.is_none() {
- error!("no username specified");
- return Ok(()); //TODO? return as error
- }
- let password = server_config
- .password
- .as_deref()
- .or(password);
- (host, port, username.unwrap(), password)
- }
- None => {
- if username.is_none() {
- error!("no username specified");
- return Ok(()); //TODO? return as error
- }
- (host, port, username.unwrap(), password)
- }
- };
- let response = send_command(Command::ServerConnect {
- host: host.to_string(),
- port,
- username: username.to_string(),
- password: password.map(|x| x.to_string()),
- accept_invalid_cert: true, //TODO
- })?
- .map(|e| (e, host));
- match response {
- Ok((e, host)) => {
- if let Some(CommandResponse::ServerConnect { welcome_message }) = e {
- println!("Connected to {}", host);
- if let Some(message) = welcome_message {
- println!("Welcome: {}", message);
- }
- }
- }
- Err(e) => {
- error!("{}", e);
- }
- };
- }
-
- Ok(())
-}
-
-fn match_server_config(matches: &clap::ArgMatches<'_>, config: &mut mumlib::config::Config) {
- if let Some(server_name) = matches.value_of("server_name") {
- let server = config.servers.iter_mut().find(|s| s.name == server_name);
- if let Some(server) = server {
- if let Some(var_name) = matches.value_of("var_name") {
- if let Some(var_value) = matches.value_of("var_value") {
- // save var_value in var_name (if it is valid)
- match var_name {
- "name" => {
- error!("use mumctl server rename instead!");
- }
- "host" => {
- server.host = var_value.to_string();
- }
- "port" => {
- server.port = Some(var_value.parse().unwrap());
- }
- "username" => {
- server.username = Some(var_value.to_string());
- }
- "password" => {
- server.password = Some(var_value.to_string()); //TODO ask stdin if empty
- }
- _ => {
- error!("variable {} not found", var_name);
- }
- };
- } else {
- // var_value is None
- // print value of var_name
- println!(
- "{}",
- match var_name {
- "name" => {
- server.name.to_string()
- }
- "host" => {
- server.host.to_string()
- }
- "port" => {
- server
- .port
- .map(|s| s.to_string())
- .unwrap_or(format!("{} not set", "error:".red()))
- }
- "username" => {
- server
- .username
- .as_ref()
- .map(|s| s.to_string())
- .unwrap_or(format!("{} not set", "error:".red()))
- }
- "password" => {
- server
- .password
- .as_ref()
- .map(|s| s.to_string())
- .unwrap_or(format!("{} not set", "error:".red()))
- }
- _ => {
- format!("{} unknown variable", "error:".red())
- }
- }
- );
- }
- } else {
- // var_name is None
- // print server config
- print!(
- "{}{}{}{}",
- format!("host: {}\n", server.host.to_string()),
- server
- .port
- .map(|s| format!("port: {}\n", s))
- .unwrap_or_else(|| "".to_string()),
- server
- .username
- .as_ref()
- .map(|s| format!("username: {}\n", s))
- .unwrap_or_else(|| "".to_string()),
- server
- .password
- .as_ref()
- .map(|s| format!("password: {}\n", s))
- .unwrap_or_else(|| "".to_string()),
- )
- }
- } else {
- // server is None
- error!("server {} not found", server_name);
- }
- } else {
- for server in config.servers.iter() {
- println!("{}", server.name);
- }
- }
-}
-
-fn match_server_rename(matches: &clap::ArgMatches<'_>, config: &mut mumlib::config::Config) {
- let prev_name = matches.value_of("prev_name").unwrap();
- let next_name = matches.value_of("next_name").unwrap();
- if let Some(server) = config.servers.iter_mut().find(|s| s.name == prev_name) {
- server.name = next_name.to_string();
- } else {
- error!("server {} not found", prev_name);
- }
-}
-
-fn match_server_remove(matches: &clap::ArgMatches<'_>, config: &mut mumlib::config::Config) {
- let name = matches.value_of("name").unwrap();
- match config.servers.iter().position(|server| server.name == name) {
- Some(idx) => {
- config.servers.remove(idx);
- }
- None => {
- error!("server {} not found", name);
- }
- };
-}
-fn match_server_add(matches: &clap::ArgMatches<'_>, config: &mut mumlib::config::Config) {
- let name = matches.value_of("name").unwrap().to_string();
- let host = matches.value_of("host").unwrap().to_string();
- // optional arguments map None to None
- let port = matches.value_of("port").map(|s| s.parse().unwrap());
- let username = matches.value_of("username").map(|s| s.to_string());
- let password = matches.value_of("password").map(|s| s.to_string());
- if config.servers.iter().any(|s| s.name == name) {
- error!("a server named {} already exists", name);
- } else {
- config.servers.push(ServerConfig {
- name,
- host,
- port,
- username,
- password,
- });
- }
-}
-
-fn parse_status(server_state: &mumlib::state::Server) {
+fn parse_state(server_state: &mumlib::state::Server) {
println!(
"Connected to {} as {}",
server_state.host, server_state.username
@@ -579,19 +505,19 @@ fn parse_status(server_state: &mumlib::state::Server) {
}
}
-fn send_command(command: Command) -> Result<mumlib::error::Result<Option<CommandResponse>>, crate::Error> {
- let mut connection = UnixStream::connect(mumlib::SOCKET_PATH).map_err(|_| Error::ConnectionError)?;
+fn send_command(command: MumCommand) -> Result<mumlib::error::Result<Option<CommandResponse>>, CliError> {
+ let mut connection = UnixStream::connect(mumlib::SOCKET_PATH).map_err(|_| CliError::ConnectionError)?;
let serialized = bincode::serialize(&command).unwrap();
- connection.write(&(serialized.len() as u32).to_be_bytes()).map_err(|_| Error::ConnectionError)?;
- connection.write(&serialized).map_err(|_| Error::ConnectionError)?;
+ connection.write(&(serialized.len() as u32).to_be_bytes()).map_err(|_| CliError::ConnectionError)?;
+ connection.write(&serialized).map_err(|_| CliError::ConnectionError)?;
- connection.read_exact(&mut [0; 4]).map_err(|_| Error::ConnectionError)?;
- bincode::deserialize_from(&mut connection).map_err(|_| Error::ConnectionError)
+ connection.read_exact(&mut [0; 4]).map_err(|_| CliError::ConnectionError)?;
+ bincode::deserialize_from(&mut connection).map_err(|_| CliError::ConnectionError)
}
-fn print_channel(channel: &Channel, depth: usize) {
+fn print_channel(channel: &MumChannel, depth: usize) {
println!(
"{}{}{}",
iter::repeat(INDENTATION).take(depth).collect::<String>(),
@@ -615,14 +541,3 @@ fn print_channel(channel: &Channel, depth: usize) {
print_channel(child, depth + 1);
}
}
-
-#[derive(Debug)]
-enum Error {
- ConnectionError
-}
-
-impl Display for Error {
- fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
- write!(f, "Unable to connect to mumd. Is mumd running?")
- }
-}