Add argument parsing and default config file.

This commit is contained in:
redxef 2023-10-15 01:18:00 +02:00
parent b76d325d60
commit 1b6c9e46be
Signed by: redxef
GPG key ID: 7DAC3AA211CBD921
2 changed files with 39 additions and 8 deletions

View file

@ -17,3 +17,4 @@ serde = { version = "1.0.188", features = ["std", "derive", "serde_derive"] }
serde_json = "1.0.107" serde_json = "1.0.107"
serde_yaml = "0.9.25" serde_yaml = "0.9.25"
tokio = { version = "1.33.0", features = ["full"] } tokio = { version = "1.33.0", features = ["full"] }
xdg = "2.5.2"

View file

@ -3,6 +3,8 @@ use tokio::time::{timeout, Duration};
use tokio::io::AsyncReadExt; use tokio::io::AsyncReadExt;
use clap::Parser; use clap::Parser;
use log::{info, debug, warn}; use log::{info, debug, warn};
use std::path::PathBuf;
use std::str::FromStr;
mod config; mod config;
mod i3ipc; mod i3ipc;
@ -16,6 +18,17 @@ use i3ipc::{Connection, MessageType};
#[derive(Parser)] #[derive(Parser)]
#[command(author, version, about, long_about = None)] #[command(author, version, about, long_about = None)]
struct Args { struct Args {
#[arg(short, long, value_name = "FILE")]
config: Option<PathBuf>,
}
impl Args {
fn finish(&mut self) {
// TODO maybe return separate type
if self.config.is_none() {
self.config = Some(xdg::BaseDirectories::with_prefix("i3toolwait").unwrap().get_config_file("config.yaml"));
}
}
} }
fn new_window_cb( fn new_window_cb(
@ -45,13 +58,24 @@ fn new_window_cb(
} }
async fn run<'a>(connection: &mut Connection<'a>, config: &Config) -> Result<(), anyhow::Error> { async fn run<'a>(connection: &mut Connection<'a>, config: &Config) -> Result<(), anyhow::Error> {
let resp = connection.communicate(&MessageType::Version, b"").await?; let (_, resp) = connection.communicate(&MessageType::Version, b"").await?;
println!("{:?}", resp); info!("i3 version is {}", resp.get("human_readable").unwrap());
for p in config.programs.iter() { for p in config.programs.iter() {
if let Some(r) = &p.run { if let Some(r) = &p.run {
let (message_type, response) = connection.communicate(&MessageType::Command, r.as_bytes()).await?; let (_, responses) = connection.communicate(&MessageType::Command, r.as_bytes()).await?;
println!("{:?}", (message_type, response)); match responses {
serde_json::Value::Array(responses) => {
for response in responses {
if let serde_json::Value::Bool(v) = response.get("success").unwrap() {
if !v {
warn!("Failed to run command {}: {}", r, response);
}
}
}
},
_ => panic!("invalid response"),
};
} }
} }
Ok(()) Ok(())
@ -59,16 +83,22 @@ async fn run<'a>(connection: &mut Connection<'a>, config: &Config) -> Result<(),
#[tokio::main] #[tokio::main]
async fn main() -> Result<()> { async fn main() -> Result<()> {
let args = std::sync::Arc::new(Args::parse());
env_logger::init_from_env(env_logger::Env::new().filter("I3TOOLWAIT_LOG").write_style("I3TOOLWAIT_LOG_STYLE")); env_logger::init_from_env(env_logger::Env::new().filter("I3TOOLWAIT_LOG").write_style("I3TOOLWAIT_LOG_STYLE"));
let mut connection = Connection::connect((i3ipc::get_socket_path().await?).as_ref())?;
let mut sub_connection = connection.clone();
let mut args = Args::parse();
args.finish();
let args = std::sync::Arc::new(args);
let mut config = String::new(); let mut config = String::new();
tokio::fs::File::open("/home/redxef/CODE/i3toolwait/i3_autostart.yaml").await?.read_to_string(&mut config).await?; if args.config.as_ref().unwrap() == &PathBuf::from_str("-").unwrap() {
tokio::io::stdin().read_to_string(&mut config).await?;
} else {
tokio::fs::File::open(args.config.as_ref().unwrap()).await?.read_to_string(&mut config).await?;
}
let config: Config = serde_yaml::from_str(&config)?; let config: Config = serde_yaml::from_str(&config)?;
let config = std::sync::Arc::new(config); let config = std::sync::Arc::new(config);
let mut connection = Connection::connect((i3ipc::get_socket_path().await?).as_ref())?;
let mut sub_connection = connection.clone();
let cb_config = config.clone(); let cb_config = config.clone();
let cb_args = args.clone(); let cb_args = args.clone();
let cb = move |a, b| {new_window_cb(a, b, &cb_config, &cb_args)}; let cb = move |a, b| {new_window_cb(a, b, &cb_config, &cb_args)};