diff --git a/src/cmus/mod.rs b/src/cmus/mod.rs index b51ebcb..5f28396 100644 --- a/src/cmus/mod.rs +++ b/src/cmus/mod.rs @@ -4,19 +4,20 @@ use std::num::ParseIntError; use std::str::FromStr; use typed_builder::TypedBuilder; -#[derive(Debug, PartialEq)] +#[derive(Debug, PartialEq, Default)] pub struct TrackMetadata { tags: HashMap, } -#[derive(Debug, PartialEq)] +#[derive(Debug, PartialEq, Default)] pub enum TrackStatus { Playing, Paused, + #[default] Stopped, } -#[derive(Debug, TypedBuilder, PartialEq)] +#[derive(Debug, TypedBuilder, PartialEq, Default)] pub struct Track { pub status: TrackStatus, pub path: String, @@ -118,7 +119,7 @@ impl TrackMetadata { TrackMetadata { tags } } - fn get(&self, key: &str) -> Option<&str> { + pub fn get(&self, key: &str) -> Option<&str> { self.tags.get(key).map(|s| s.as_str()) } } @@ -127,9 +128,9 @@ impl Track { /// Returns the name of the track. /// /// This is the title, if it exists, otherwise it's the file name without the extension. - pub fn get_name(&self) -> String { + pub fn get_name(&self) -> &str { self.metadata.get("title").unwrap_or_else(|| self.path.split('/').last() - .unwrap_or("").split_once(".").unwrap_or(("", "")).0).to_string() + .unwrap_or("").split_once(".").unwrap_or(("", "")).0) } } diff --git a/src/utils.rs b/src/utils.rs new file mode 100644 index 0000000..938a8b1 --- /dev/null +++ b/src/utils.rs @@ -0,0 +1,59 @@ +use crate::cmus; + +pub fn search_for_cover_image(search_directory: &str, max_depth: u8) -> Option { + + + + None +} + +/// Replace all the placeholders in the template with their matching value. +#[inline] +pub fn process_template_placeholders(template: &String, track: &cmus::Track) -> String { + 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 == '}' { // 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" => track.get_name(), + _ => track.metadata.get(&key).unwrap_or(""), + }); + } else { + key.push(c); + } + } + + processed +} + +#[cfg(test)] +mod tests { + use super::*; + use std::str::FromStr; + use test_context::{test_context, TestContext}; + + struct TestContextWithFullTrack { + track: cmus::Track, + } + + impl TestContext for TestContextWithFullTrack { + fn setup() -> Self { + Self { + track: cmus::Track::from_str(include_str!("../tests/samples/cmus-remote-output-with-all-tags.txt")).unwrap() + } + } + } + + #[test_context(TestContextWithFullTrack)] + #[test] + fn test_process_path_template(ctx: &TestContextWithFullTrack) { + let cover_path_template = String::from("{title}/{artist}/{album}/{tracknumber}"); + let cover_path = process_template_placeholders(&cover_path_template, &ctx.track); + + assert_eq!(cover_path, "Photograph/Alex Goot/Alex Goot & Friends, Vol. 3/8"); + } +}