Process the settings place holders in the template
This commit is contained in:
parent
cb164f962a
commit
5488404fb3
5 changed files with 129 additions and 25 deletions
50
Cargo.lock
generated
50
Cargo.lock
generated
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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}");
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
},
|
||||
})
|
||||
);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue