From 2d3d297f1411e88de69423b4888d1c8132416a5d Mon Sep 17 00:00:00 2001 From: Jakub Trzeciak Date: Thu, 15 Feb 2024 22:35:00 +0100 Subject: refactor old tagging code --- Cargo.lock | 33 +++++++----------- Cargo.toml | 2 +- src/main.rs | 110 +++++++++++++++++------------------------------------------- 3 files changed, 45 insertions(+), 100 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a7c3d28..421d539 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -65,12 +65,6 @@ dependencies = [ "windows-sys", ] -[[package]] -name = "base64" -version = "0.21.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" - [[package]] name = "byteorder" version = "1.5.0" @@ -138,6 +132,12 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "data-encoding" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e962a19be5cfc3f3bf6dd8f61eb50107f356ad6270fbb3ed41476571db78be5" + [[package]] name = "flate2" version = "1.0.28" @@ -156,25 +156,24 @@ checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" [[package]] name = "lofty" -version = "0.13.0" +version = "0.18.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0cb2b21027aa98f860de475b3ee8b10f36df689121b5752efeb7a64bec1f4d45" +checksum = "f75066eb1d25a7047fb2667edb410ae2592439ed81546f95c28b0a1c7d7d3818" dependencies = [ - "base64", "byteorder", + "data-encoding", "flate2", "lofty_attr", "log", "ogg_pager", - "once_cell", "paste", ] [[package]] name = "lofty_attr" -version = "0.7.0" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9482ad911db377f8362c658aff576aac289c84cf5c25ca058e2c49d9bc3301dc" +checksum = "764b60e1ddd07e5665a6a17636a95cd7d8f3b86c73503a69c32979d05f72f3cf" dependencies = [ "proc-macro2", "quote", @@ -213,19 +212,13 @@ dependencies = [ [[package]] name = "ogg_pager" -version = "0.5.0" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d218a406e5de88e1c492d0162d569916f7436efe851ba5cc40a4bf4fa97cb40" +checksum = "c949d63b387b25c332f6e39d1762dd4b405008289dd7681f02c258b1294653ca" dependencies = [ "byteorder", ] -[[package]] -name = "once_cell" -version = "1.19.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" - [[package]] name = "paste" version = "1.0.14" diff --git a/Cargo.toml b/Cargo.toml index 3f05b05..b8caa88 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,6 +6,6 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -lofty = "0.13.0" +lofty = "0.18.2" regex = "1.8.3" clap = { version = "4.4.18", features = ["derive"] } diff --git a/src/main.rs b/src/main.rs index dfc1906..0c65b30 100644 --- a/src/main.rs +++ b/src/main.rs @@ -31,95 +31,47 @@ struct InnerTag { } impl InnerTag { - pub fn empty() -> InnerTag { - InnerTag {title: "".into(), artist: None, album: None, track: None} + fn from_parts(title: String, artist: Option, album: Option, track: Option) -> Self { + Self { title, artist, album, track } } - pub fn from(name: &str) -> Result{ - let mut inner_tag: InnerTag = InnerTag::empty(); - - let mut tags: Vec = Vec::new(); - - { // TODO make it faster and cleaner - let mut text: String = "".into(); - let mut connected = false; - - for s in name.split("-") { - if text == "" { - text = s.into(); - } else { - if s == "" { - connected = true; - text += "-"; - } else if connected { - text += s; - connected = false; - } else { - tags.push(text); - text = s.into(); - } - } - } - - tags.push(text); - } - - match tags.len() { - 1 => { - inner_tag.title = tags.remove(0); - }, - 2 => { - inner_tag.artist = Some(tags.remove(0)); - inner_tag.title = tags.remove(0); - }, - 3 => { - inner_tag.artist = Some(tags.remove(0)); - inner_tag.album = Some(tags.remove(0)); - inner_tag.title = tags.remove(0); - }, - 4 => { - inner_tag.artist = Some(tags.remove(0)); - inner_tag.album = Some(tags.remove(0)); - inner_tag.track = Some(tags.remove(0).parse().unwrap()); - inner_tag.title = tags.remove(0); - }, - 5 => { - inner_tag.artist = Some(tags.remove(0)); - inner_tag.album = Some(tags.remove(0)); - inner_tag.track = Some(tags.remove(0).parse().unwrap()); - inner_tag.title = tags.remove(1); - }, - _ => panic!("🔥 To many tags in {}", name) + pub fn from(name: &str) -> Result { + // Replace '--' with a unique placeholder that is unlikely to be part of any filename. + // Ensure this placeholder does not accidentally create new splitting points. + let placeholder = "\u{FDD0}"; // Use a Unicode non-character as a placeholder. + let sanitized_name = name.replace("--", placeholder); + + let parts: Vec<_> = sanitized_name.split('-') + .map(|part| part.replace(placeholder, "-")) + .collect(); + + let err = Err(format!("🔥 Invalid tag format in filename: {}", name)); + + match parts.as_slice() { + [title] => Ok(Self::from_parts(title.to_string(), None, None, None)), + [artist, title] => Ok(Self::from_parts(title.to_string(), Some(artist.to_string()), None, None)), + [artist, album, title] => Ok(Self::from_parts(title.to_string(), Some(artist.to_string()), Some(album.to_string()), None)), + [artist, album, track_str, title] => track_str.parse::().map_or(err, |track| Ok(Self::from_parts(title.to_string(), Some(artist.to_string()), Some(album.to_string()), Some(track)))), + [artist, album, track_str, title, _] => track_str.parse::().map_or(err, |track| Ok(Self::from_parts(title.to_string(), Some(artist.to_string()), Some(album.to_string()), Some(track)))), + _ => err, } - - return Ok(inner_tag); } } -fn tag_ogg_file(path: &Path) -> Result<(), LoftyError> { - let mut tagged_file = Probe::open(path) - .expect("ERROR: Bad path provided!") - .read()?; +fn tag_ogg_file(path: &Path) -> Result<(), Box> { + let mut probed_file = Probe::open(path)?.read()?; - let tag = match tagged_file.primary_tag_mut() { - Some(primary_tag) => primary_tag, - None => { - if let Some(first_tag) = tagged_file.first_tag_mut() { - first_tag - } else { - let tag_type = tagged_file.primary_tag_type(); + if probed_file.primary_tag_mut().is_none() { + let tag_type = probed_file.primary_tag_type(); + eprintln!("👻 No tags found, creating a new tag of type `{tag_type:?}`"); + probed_file.insert_tag(Tag::new(tag_type)); + } - eprintln!("👻 No tags found, creating a new tag of type `{tag_type:?}`"); - tagged_file.insert_tag(Tag::new(tag_type)); + let tag = probed_file.primary_tag_mut().unwrap(); - tagged_file.primary_tag_mut().unwrap() - } - }, - }; + let name = path.file_name().and_then(|n| n.to_str()).expect("Filename is not valid UTF-8"); - let path_without_ext = path.with_extension(""); - let name = path_without_ext.file_name().unwrap().to_str().unwrap(); - let inner_tag = InnerTag::from(name).unwrap(); + let inner_tag = InnerTag::from(name)?; tag.clear(); tag.set_title(inner_tag.title); -- cgit v1.2.3