From 72fbc37687e5c565d26c293061fa54a478d2f974 Mon Sep 17 00:00:00 2001 From: Valerie Date: Mon, 27 Jun 2022 19:23:56 -0400 Subject: [PATCH] initial commit --- .gitignore | 1 + Cargo.lock | 25 +++++++++ Cargo.toml | 9 +++ src/error.rs | 20 +++++++ src/main.rs | 151 +++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 206 insertions(+) create mode 100644 .gitignore create mode 100644 Cargo.lock create mode 100644 Cargo.toml create mode 100644 src/error.rs create mode 100644 src/main.rs diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/target diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..bb1ded8 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,25 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "config" +version = "0.0.1" +dependencies = [ + "toml", +] + +[[package]] +name = "serde" +version = "1.0.137" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61ea8d54c77f8315140a05f4c7237403bf38b72704d031543aa1d16abbf517d1" + +[[package]] +name = "toml" +version = "0.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d82e1a7758622a465f8cee077614c73484dac5b836c02ff6a40d5d1010324d7" +dependencies = [ + "serde", +] diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..efaceb4 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "config" +version = "0.0.1" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +toml = "0.5.9" diff --git a/src/error.rs b/src/error.rs new file mode 100644 index 0000000..473552a --- /dev/null +++ b/src/error.rs @@ -0,0 +1,20 @@ +use std::{ + path::PathBuf, + process::exit +}; + +pub fn missing_config(path: &PathBuf) { + println!("config: no config file found at {:?}", path); + exit(1); +} + +pub fn no_section(section: &String) { + println!("config: nothing specified for \"{}\"", section); + exit(3); +} + +pub fn no_property(section: &String, property: &str) { + println!("config: \"{}\" has no property \"{}\"", section, property); + exit(4); +} + diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..067be68 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,151 @@ +use std::{ + env::{ args, current_dir, var }, + error::Error, + fs::read_to_string, + path::PathBuf, + process::{ + exit, + + Command, + Stdio + } +}; + +use toml::Value; + +mod error; + +pub const VERSION: &str = "0.0.1"; + +fn main() -> Result<(), Box>{ + let home_dir = var("HOME").unwrap(); + let mut config_path = PathBuf::from(&home_dir); + config_path.push(".config/config.toml"); + if !config_path.exists() { + error::missing_config(&config_path); + } + + let raw_conf = read_to_string(config_path)?; + let toml_conf: Value = toml::from_str(raw_conf.as_str())?; + let config = toml_conf.as_table().unwrap(); + + let i_editor = var("EDITOR"); + let editor: Option = if i_editor.is_ok() { Some(i_editor.unwrap()) } else { None }; + + let args: Vec = args().skip(1).collect(); + let mut dir = false; + let mut list = false; + let mut path = false; + { + if args.len() == 0 { + help_text(); + exit(2); + } + match args[0].as_str() { + "-d" | + "--dir" => dir = true, + "-l" | + "--list" => list = true, + "-p" | + "--path" => path = true, + "-h" | + "--help" => { + help_text(); + return Ok(()); + } + _ => {} + } + } + + if list { + for key in config.keys() { + println!("{}", key); + } + } + + let entry = &args[args.len() - 1]; + let i_section = config.get(entry); + if i_section.is_none() { + error::no_section(entry); + } + let section = i_section.unwrap().as_table().unwrap(); + + let prop_path = section.get("path"); + if dir { + if prop_path.is_none() { + error::no_property(entry, "path"); + } + let i_file_path = prop_path.unwrap().as_str().unwrap(); + let file_path = PathBuf::from(i_file_path); + if file_path.is_dir() { + path = true; + } else { + let parent = file_path.parent().unwrap(); + println!("{}", parent.to_str().unwrap()); + return Ok(()); + } + } + if path { + if prop_path.is_none() { + error::no_property(entry, "path"); + } + let file_path = prop_path.unwrap().as_str().unwrap(); + println!("{}", file_path); + return Ok(()); + } + + let prop_command = section.get("command"); + let raw_command: String; + if prop_command.is_none() { + if editor.is_none() { + error::no_property(entry, "command"); + } + raw_command = editor.unwrap(); + } else { + raw_command = prop_command.unwrap().as_str().unwrap().to_string(); + } + let mut parts = raw_command.split_whitespace(); + let command = parts.next().unwrap(); + + let prop_shell = section.get("shell"); + let shell: bool; + if prop_shell.is_some() { + shell = prop_shell.unwrap().as_bool().unwrap(); + } else { + shell = false; + } + + let mut process = Command::new(command); + process.current_dir(current_dir()?); + let mut arguments: Vec<&str> = parts.collect(); + if prop_path.is_some() { + let target = prop_path.unwrap().as_str().unwrap(); + arguments.push(target); + } + if arguments.len() != 0 { + process.args(arguments); + } + if shell { + process + .stdin(Stdio::inherit()) + .stdout(Stdio::inherit()) + .stderr(Stdio::inherit()); + process.output()?; + } else { + process + .stdin(Stdio::null()) + .stdout(Stdio::null()) + .stderr(Stdio::null()); + process.spawn()?; + } + + return Ok(()); +} + +fn help_text() { + println!("config v{}", VERSION); + println!("Valerie Wolfe