Process the settings place holders in the template

This commit is contained in:
Anas Elgarhy 2023-02-21 04:41:12 +02:00
parent cb164f962a
commit 5488404fb3
No known key found for this signature in database
GPG key ID: 0501802A1D496528
5 changed files with 129 additions and 25 deletions

50
Cargo.lock generated
View file

@ -233,6 +233,7 @@ dependencies = [
"log",
"lrc",
"notify-rust",
"parse-display",
"pretty_env_logger",
"regex",
"serde",
@ -1138,6 +1139,32 @@ dependencies = [
"windows-sys 0.45.0",
]
[[package]]
name = "parse-display"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6f96cc033d72896bb9a2c239a14e1141c3e2eae6d649e7c10ef4e598d66bc86c"
dependencies = [
"once_cell",
"parse-display-derive",
"regex",
]
[[package]]
name = "parse-display-derive"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e5587062be441f3d868f7c4c9d13c67f286b03aa679d7f8176ef80bf2ee79e5d"
dependencies = [
"once_cell",
"proc-macro2",
"quote",
"regex",
"regex-syntax",
"structmeta",
"syn",
]
[[package]]
name = "pin-project"
version = "1.0.12"
@ -1524,6 +1551,29 @@ version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
[[package]]
name = "structmeta"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1bd9c2155aa89fb2c2cb87d99a610c689e7c47099b3e9f1c8a8f53faf4e3d2e3"
dependencies = [
"proc-macro2",
"quote",
"structmeta-derive",
"syn",
]
[[package]]
name = "structmeta-derive"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bafede0d0a2f21910f36d47b1558caae3076ed80f6f3ad0fc85a91e6ba7e5938"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "strum"
version = "0.22.0"

View file

@ -16,6 +16,7 @@ typed-builder = "0.12.0"
log = { version = "0.4.17", optional = true }
pretty_env_logger = { version = "0.4.0", optional = true }
thiserror = "1.0.38"
parse-display = "0.8.0"
[dependencies.clap]
version = "4.1.4"

View file

@ -5,6 +5,7 @@ pub mod query;
use crate::cmus::query::CmusQueryResponse;
#[cfg(feature = "debug")]
use log::{debug, info};
use parse_display::Display;
use std::collections::HashMap;
use std::fmt::Debug;
use std::num::ParseIntError;
@ -14,6 +15,27 @@ use typed_builder::TypedBuilder;
pub trait TemplateProcessor {
fn process(&self, template: &String) -> String;
fn get_keys(template: &String) -> Vec<String> {
let mut keys = Vec::new(); // Just a buffer to store the keys.
let mut key = String::new(); // Just a buffer to build the key.
for c in template.chars() {
if c == '{' {
key = String::new();
} else if c == '}' {
#[cfg(feature = "debug")]
debug!("Found key: {}", key);
keys.push(key.clone());
} else {
key.push(c);
}
}
#[cfg(feature = "debug")]
debug!("Found keys: {:?}", keys);
keys
}
}
#[derive(Debug, PartialEq, Default, Clone)]
@ -21,7 +43,7 @@ pub struct TrackMetadata {
tags: HashMap<String, String>,
}
#[derive(Debug, PartialEq, Default, Clone)]
#[derive(Display, Debug, PartialEq, Default, Clone)]
pub enum TrackStatus {
Playing,
Paused,
@ -72,26 +94,19 @@ impl TemplateProcessor for Track {
}
let mut processed = template.clone();
let mut key = String::new(); // Just a buffer to store the key.
for c in template.chars() {
if c == '{' {
key = String::new();
} else if c == '}' {
#[cfg(feature = "debug")]
debug!("Replacing the placeholder {{{key}}} with its matching value.");
// Replace the key with their matching value if exists, if not replace with the empty string.
processed = processed.replace(
&format!("{{{}}}", key),
match key.as_str() {
"title" => self.get_name(),
_ => self.metadata.get(&key).unwrap_or(""),
},
);
} else {
key.push(c);
Self::get_keys(template).iter().for_each(|key| {
#[cfg(feature = "debug")]
debug!("Replacing the placeholder {{{key}}} with its matching value.");
// Replace the key with their matching value if exists, if not replace with the empty string.
let status = self.status.to_string();
if let Some(value) = match key.as_str() {
"status" => Some(status.as_str()),
"title" => Some(self.get_name()),
_ => self.metadata.get(&key),
} {
processed = processed.replace(&format!("{{{key}}}"), value);
}
}
});
#[cfg(feature = "debug")]
debug!("Processed template: {processed}");

View file

@ -1,6 +1,8 @@
use crate::cmus::CmusError;
use crate::cmus::{CmusError, TemplateProcessor};
#[cfg(feature = "debug")]
use log::{debug, info};
use parse_display::Display;
use std::fmt::{Display, Formatter};
use std::num::ParseIntError;
use std::str::FromStr;
@ -13,7 +15,7 @@ pub struct PlayerSettings {
pub volume: Volume,
}
#[derive(Debug, PartialEq, Default, Clone)]
#[derive(Display, Debug, PartialEq, Default, Clone)]
pub enum Shuffle {
#[default]
Off,
@ -27,7 +29,7 @@ pub struct Volume {
pub right: u8,
}
#[derive(Debug, PartialEq, Default, Clone)]
#[derive(Display, Debug, PartialEq, Default, Clone)]
pub enum AAAMode {
#[default]
All,
@ -35,6 +37,42 @@ pub enum AAAMode {
Artist,
}
impl TemplateProcessor for PlayerSettings {
fn process(&self, template: &String) -> String {
#[cfg(feature = "debug")]
{
info!("Processing template: {}", template);
debug!("Processing template with player settings: {:?}", self);
}
let mut processed = template.clone();
Self::get_keys(template).iter().for_each(|key| {
let value = match key.as_str() {
"repeat" => self.repeat.to_string(),
"repeat_current" => self.repeat_current.to_string(),
"shuffle" => self.shuffle.to_string(),
"aaa_mode" => self.aaa_mode.to_string(),
"volume_left" => self.volume.left.to_string(),
"volume_right" => self.volume.right.to_string(),
"volume" => {
if self.volume.left == self.volume.right {
self.volume.left.to_string()
} else {
format!("{}:{}", self.volume.left, self.volume.right)
}
}
_ => "".to_string(),
};
processed = processed.replace(&format!("{{{key}}}"), &value);
});
#[cfg(feature = "debug")]
info!("Processed template: {}", processed);
processed
}
}
impl FromStr for AAAMode {
type Err = CmusError;
@ -165,7 +203,7 @@ mod tests {
volume: Volume {
left: 46,
right: 46,
}
},
})
);
}

View file

@ -1,9 +1,9 @@
#![feature(assert_matches)]
use crate::cmus::TemplateProcessor;
#[cfg(feature = "debug")]
use log::{debug, info};
use std::path::Path;
use crate::cmus::TemplateProcessor;
pub mod cmus;
pub mod notification;