v0.1.4, Impl advanced --regex-cmd usage

Can now use captures with `--regex-cmd` to specify output text and
output text color.
This commit is contained in:
Stephen Seo 2022-08-23 17:02:35 +09:00
parent 3c0e5069ca
commit 456d58c6f4
5 changed files with 71 additions and 13 deletions

2
Cargo.lock generated
View file

@ -141,7 +141,7 @@ dependencies = [
[[package]] [[package]]
name = "swaybar_info" name = "swaybar_info"
version = "0.1.3" version = "0.1.4"
dependencies = [ dependencies = [
"chrono", "chrono",
"regex", "regex",

View file

@ -1,6 +1,6 @@
[package] [package]
name = "swaybar_info" name = "swaybar_info"
version = "0.1.3" version = "0.1.4"
edition = "2021" edition = "2021"
description = "Provides swaybar with info to be displayed" description = "Provides swaybar with info to be displayed"
license = "MIT" license = "MIT"
@ -12,4 +12,4 @@ repository = "https://github.com/Stephen-Seo/swaybar_info"
serde_json = "1.0" serde_json = "1.0"
serde = { version = "1.0", features = ["derive"] } serde = { version = "1.0", features = ["derive"] }
chrono = "0.4" chrono = "0.4"
regex = "1.5" regex = "1.6"

View file

@ -62,6 +62,29 @@ Put the following in your `~/.config/sway/config` (assuming the binary is at
#status_command $HOME/.config/sway/swaybar_info --time-format="%Y-%m-%d %R:%S" #status_command $HOME/.config/sway/swaybar_info --time-format="%Y-%m-%d %R:%S"
} }
## Advanced Usage of `--regex-cmd`
If the regex provided to `swaybar_info` has two captures, the first capture will
be used as the text to be displayed, and the second capture will be expected to
be the color string (such as FFFFFF for white, or 44FF44 for a lighter green).
For example, if the script invoked with `--regex-cmd` has output like the
following:
MPD Title | MPD Album | playingCOLORSPLIT44FF44
That sometimes becomes:
MPD is not running
Then this text can be parsed with a regex like:
status_command $HOME/.config/sway/swaybar_info \
'--regex-cmd=$HOME/scripts/mpc/mpcCommand.sh[SPLIT]simple[SPLIT]^\(.\*?\)\(?:COLORSPLIT\)?\([A-F0-9]{6}\)?$'
Note that some characters like `*` or `(` had to be escaped because they are
being passed verbatim to a shell.
## Dependencies ## Dependencies
Uses [`serde_json`](https://crates.io/crates/serde_json), Uses [`serde_json`](https://crates.io/crates/serde_json),

View file

@ -9,6 +9,11 @@ pub enum Error {
Generic(String), Generic(String),
} }
pub struct ExternalRegexResult {
pub matched: String,
pub color: Option<String>,
}
impl From<io::Error> for Error { impl From<io::Error> for Error {
fn from(io_error: io::Error) -> Self { fn from(io_error: io::Error) -> Self {
Self::IO(io_error) Self::IO(io_error)
@ -47,7 +52,11 @@ impl std::error::Error for Error {
} }
} }
pub fn get_cmd_output(cmd: &str, args: &[&str], regex: &Regex) -> Result<String, Error> { pub fn get_cmd_output(
cmd: &str,
args: &[&str],
regex: &Regex,
) -> Result<ExternalRegexResult, Error> {
let mut cmd_builder = Command::new(cmd); let mut cmd_builder = Command::new(cmd);
for arg in args { for arg in args {
cmd_builder.arg(arg); cmd_builder.arg(arg);
@ -55,10 +64,33 @@ pub fn get_cmd_output(cmd: &str, args: &[&str], regex: &Regex) -> Result<String,
let output = cmd_builder.output()?; let output = cmd_builder.output()?;
let stdout_output: String = String::from_utf8(output.stdout)?; let stdout_output: String = String::from_utf8(output.stdout)?;
let regex_captures = regex let regex_captures = regex
.captures(&stdout_output) .captures(stdout_output.trim())
.ok_or_else(|| Error::from("Regex returned empty matches".to_owned()))?; .ok_or_else(|| Error::from("Regex returned empty matches".to_owned()))?;
let regex_match = regex_captures let mut color: Option<String> = None;
let matched: String = if regex_captures.len() == 1 {
regex_captures
.get(0) .get(0)
.ok_or_else(|| Error::from("Failed to get regex match".to_owned()))?; .ok_or_else(|| Error::from("Failed to get regex 0".to_owned()))?
Ok(regex_match.as_str().to_owned()) .as_str()
.to_owned()
} else {
//if regex_captures.len() >= 2 {
regex_captures
.get(1)
.ok_or_else(|| Error::from("Failed to get regex 1".to_owned()))?
.as_str()
.to_owned()
};
match regex_captures.len() {
3 => color = regex_captures.get(2).map(|m| m.as_str().to_owned()),
4.. => {
return Err(Error::from(
"Too many captures in regex, up to 2 is allowed".to_owned(),
))
}
_ => (),
}
Ok(ExternalRegexResult { matched, color })
} }

View file

@ -188,15 +188,18 @@ fn main() {
{ {
for (idx, (cmd, args, regex)) in cmds.iter().enumerate() { for (idx, (cmd, args, regex)) in cmds.iter().enumerate() {
let cmd_result = external::get_cmd_output(cmd, args, regex); let cmd_result = external::get_cmd_output(cmd, args, regex);
if let Ok(cmd_string) = cmd_result { if let Ok(cmd_struct) = cmd_result {
if is_empty { if is_empty {
let cmd_obj = let mut cmd_obj = SwaybarObject::from_string(
SwaybarObject::from_string(format!("regex_cmd_{}", idx), cmd_string); format!("regex_cmd_{}", idx),
cmd_struct.matched,
);
cmd_obj.color = cmd_struct.color;
array.push_object(cmd_obj); array.push_object(cmd_obj);
} else if let Some(cmd_obj) = } else if let Some(cmd_obj) =
array.get_by_name_mut(&format!("regex_cmd_{}", idx)) array.get_by_name_mut(&format!("regex_cmd_{}", idx))
{ {
cmd_obj.update_as_generic(cmd_string, None); cmd_obj.update_as_generic(cmd_struct.matched, cmd_struct.color);
} }
} else if let Err(e) = cmd_result { } else if let Err(e) = cmd_result {
let mut stderr_handle = io::stderr().lock(); let mut stderr_handle = io::stderr().lock();