diff --git a/assets/meep.flac b/assets/meep.flac new file mode 100644 index 0000000..53d4ba6 Binary files /dev/null and b/assets/meep.flac differ diff --git a/src/components/flac_tag.rs b/src/components/flac_tag.rs index 2320d60..c62f7ba 100644 --- a/src/components/flac_tag.rs +++ b/src/components/flac_tag.rs @@ -125,12 +125,9 @@ impl AudioTagEdit for FlacTag { } fn track_number(&self) -> Option { - if let Some(Ok(n)) = self.get_first("TRACKNUMBER").map(|x| x.parse::()) { - Some(n) - } else { - None - } + self.track_number_pair().0 } + fn set_track_number(&mut self, v: u16) { self.set_first("TRACKNUMBER", &v.to_string()) } @@ -140,7 +137,8 @@ impl AudioTagEdit for FlacTag { if let Some(Ok(n)) = self.get_first("TOTALTRACKS").map(|x| x.parse::()) { Some(n) } else { - None + // Support "NN/MM" in the style of ID3-style TRCK. + self.track_number_pair().1 } } fn set_total_tracks(&mut self, v: u16) { @@ -214,3 +212,18 @@ impl AudioTagWrite for FlacTag { Ok(()) } } + +impl FlacTag { + fn track_number_pair(&self) -> (Option, Option) { + if let Some(s) = self.get_first("TRACKNUMBER") { + let mut parts = s.split("/").fuse().map(|t| t.parse().ok()); + // Manually unpack the first two items instead of using + // collect() so that we can avoid allocating a Vec. + let track = parts.next().flatten(); + let total = parts.next().flatten(); + (track, total) + } else { + (None, None) + } + } +} diff --git a/tests/io.rs b/tests/io.rs index 744ab99..04688fd 100644 --- a/tests/io.rs +++ b/tests/io.rs @@ -52,3 +52,14 @@ macro_rules! test_file { test_file!(test_mp3, "assets/a.mp3"); test_file!(test_m4a, "assets/a.m4a"); test_file!(test_flac, "assets/a.flac"); + +#[test] +fn test_id3_style_track_number() { + // Verify that we can consume TRACKNUMER tags in the style of the + // ID3 TRCK tag. This is non-standard (for Vorbis comments) but + // other tools (such as easytags) will read it (but, AFAIK, not + // write it). + let tags = Tag::default().read_from_path("assets/meep.flac").unwrap(); + assert_eq!(tags.track_number(), Some(1)); + assert_eq!(tags.total_tracks(), Some(6)); +}