diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/main.rs | 110 |
1 files changed, 31 insertions, 79 deletions
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<String>, album: Option<String>, track: Option<u32>) -> Self { + Self { title, artist, album, track } } - pub fn from(name: &str) -> Result<InnerTag, Error>{ - let mut inner_tag: InnerTag = InnerTag::empty(); - - let mut tags: Vec<String> = 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<Self, String> { + // 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::<u32>().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::<u32>().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<dyn std::error::Error>> { + 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); |