From d2d1bedafa5e75efe092aac9ac388c873e9cdc44 Mon Sep 17 00:00:00 2001 From: Tianyi Date: Tue, 27 Oct 2020 02:40:57 +0000 Subject: [PATCH] v0.2.3 --- CHANGELOG.md | 6 +++++- Cargo.toml | 2 +- README.md | 15 ++++++++++++--- src/flac_tag.rs | 28 ++++++++++++++++------------ src/id3_tag.rs | 28 ++++++++++++++++------------ src/lib.rs | 14 ++++++++++++++ src/mp4_tag.rs | 29 +++++++++++++++++++++++++++++ tests/conv.rs | 14 ++++++++++++-- tests/io.rs | 19 ++++++++++--------- 9 files changed, 115 insertions(+), 40 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b4361953..a75233a8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,8 @@ -## [0.2.2] 2020-10-28 +## [0.2.3] 2020-10-27 + +- multiple artists + +## [0.2.2] 2020-10-27 - Conversion between tag types without macro; removed the macro introduced in v0.2.0 diff --git a/Cargo.toml b/Cargo.toml index f8cf3105..1341875e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "audiotags" -version = "0.2.2" +version = "0.2.3" authors = ["Tianyi "] edition = "2018" description = "Unified IO for different types of audio metadata" diff --git a/README.md b/README.md index e213fbf5..d80b13bc 100644 --- a/README.md +++ b/README.md @@ -87,13 +87,22 @@ fn main() { mp4tag.write_to_path(M4A_FILE).unwrap(); // reload the tag from the m4a file; this time specifying the tag type (you can also use `default()`) - let mp4tag_reload = Tag::with_tag_type(TagType::Mp4) + let mut mp4tag = Tag::with_tag_type(TagType::Mp4) .read_from_path(M4A_FILE) .unwrap(); // the tag originated from an mp3 file is successfully written to an m4a file! - assert_eq!(mp4tag_reload.title(), Some("title from mp3 file")); + assert_eq!(mp4tag.title(), Some("title from mp3 file")); + // multiple artists + mp4tag.add_artist("artist1 of mp4"); + mp4tag.add_artist("artist2 of mp4"); + assert_eq!( + mp4tag.artists(), + Some(vec!["artist1 of mp4", "artist2 of mp4"]) + ); + // convert to id3 tag, which does not support multiple artists + let mp3tag = mp4tag.into_tag(TagType::Id3v2); + assert_eq!(mp3tag.artist(), Some("artist1 of mp4;artist2 of mp4")); } - ``` ## Supported Formats diff --git a/src/flac_tag.rs b/src/flac_tag.rs index f397e023..b1084d38 100644 --- a/src/flac_tag.rs +++ b/src/flac_tag.rs @@ -9,22 +9,26 @@ impl<'a> From> for FlacTag { fn from(inp: AnyTag<'a>) -> Self { let mut t = FlacTag::default(); inp.title().map(|v| t.set_title(v)); - inp.artists().map(|i| { - i.iter().fold(String::new(), |mut v, a| { - v.push_str(&a); - v.push_str(SEP_ARTIST); - v + inp.artists() + .map(|i| { + i.iter().fold(String::new(), |mut v, a| { + v.push_str(&a); + v.push_str(SEP_ARTIST); + v + }) }) - }); + .map(|v| t.set_artist(&v[..v.len() - 1])); inp.year.map(|v| t.set_year(v)); inp.album_title().map(|v| t.set_album_title(v)); - inp.album_artists().map(|i| { - i.iter().fold(String::new(), |mut v, a| { - v.push_str(&a); - v.push_str(SEP_ARTIST); - v + inp.album_artists() + .map(|i| { + i.iter().fold(String::new(), |mut v, a| { + v.push_str(&a); + v.push_str(SEP_ARTIST); + v + }) }) - }); + .map(|v| t.set_album_artist(&v[..v.len() - 1])); inp.track_number().map(|v| t.set_track_number(v)); inp.total_tracks().map(|v| t.set_total_tracks(v)); inp.disc_number().map(|v| t.set_disc_number(v)); diff --git a/src/id3_tag.rs b/src/id3_tag.rs index 3b4f5900..309632ad 100644 --- a/src/id3_tag.rs +++ b/src/id3_tag.rs @@ -64,22 +64,26 @@ impl<'a> From> for id3::Tag { fn from(inp: AnyTag<'a>) -> Self { let mut t = id3::Tag::new(); inp.title().map(|v| t.set_title(v)); - inp.artists().map(|i| { - i.iter().fold(String::new(), |mut v, a| { - v.push_str(&a); - v.push_str(SEP_ARTIST); - v + inp.artists() + .map(|i| { + i.iter().fold(String::new(), |mut v, a| { + v.push_str(&a); + v.push_str(SEP_ARTIST); + v + }) }) - }); + .map(|v| t.set_artist(&v[..v.len() - 1])); inp.year.map(|v| t.set_year(v)); inp.album_title().map(|v| t.set_album(v)); - inp.album_artists().map(|i| { - i.iter().fold(String::new(), |mut v, a| { - v.push_str(&a); - v.push_str(SEP_ARTIST); - v + inp.album_artists() + .map(|i| { + i.iter().fold(String::new(), |mut v, a| { + v.push_str(&a); + v.push_str(SEP_ARTIST); + v + }) }) - }); + .map(|v| t.set_album_artist(&v[..v.len() - 1])); inp.track_number().map(|v| t.set_track(v as u32)); inp.total_tracks().map(|v| t.set_total_tracks(v as u32)); inp.disc_number().map(|v| t.set_disc(v as u32)); diff --git a/src/lib.rs b/src/lib.rs index 546a2944..41b4c1a7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -400,6 +400,13 @@ pub trait AudioTagIo { fn set_artist(&mut self, artist: &str); fn remove_artist(&mut self); + fn artists(&self) -> Option> { + self.artist().map(|v| vec![v]) + } + fn add_artist(&mut self, artist: &str) { + self.set_artist(artist); + } + fn year(&self) -> Option; fn set_year(&mut self, year: i32); fn remove_year(&mut self); @@ -438,6 +445,13 @@ pub trait AudioTagIo { fn set_album_artist(&mut self, v: &str); fn remove_album_artist(&mut self); + fn album_artists(&self) -> Option> { + self.artist().map(|v| vec![v]) + } + fn add_album_artist(&mut self, artist: &str) { + self.set_album_artist(artist); + } + fn album_cover(&self) -> Option; fn set_album_cover(&mut self, cover: Picture); fn remove_album_cover(&mut self); diff --git a/src/mp4_tag.rs b/src/mp4_tag.rs index 8f770f2f..54b58215 100644 --- a/src/mp4_tag.rs +++ b/src/mp4_tag.rs @@ -117,6 +117,20 @@ impl AudioTagIo for Mp4Tag { fn set_artist(&mut self, artist: &str) { self.inner.set_artist(artist) } + fn artists(&self) -> Option> { + let v = self.inner.artists().fold(Vec::new(), |mut v, a| { + v.push(a); + v + }); + if v.len() > 0 { + Some(v) + } else { + None + } + } + fn add_artist(&mut self, v: &str) { + self.inner.add_artist(v); + } fn year(&self) -> Option { self.inner.year().and_then(|x| str::parse(x).ok()) @@ -139,6 +153,21 @@ impl AudioTagIo for Mp4Tag { self.inner.set_album_artist(v) } + fn album_artists(&self) -> Option> { + let v = self.inner.album_artists().fold(Vec::new(), |mut v, a| { + v.push(a); + v + }); + if v.len() > 0 { + Some(v) + } else { + None + } + } + fn add_album_artist(&mut self, v: &str) { + self.inner.add_album_artist(v); + } + fn album_cover(&self) -> Option { use mp4ameta::Data::*; self.inner.artwork().and_then(|data| match data { diff --git a/tests/conv.rs b/tests/conv.rs index 7dd01964..dcff842c 100644 --- a/tests/conv.rs +++ b/tests/conv.rs @@ -14,9 +14,19 @@ fn test_convert_mp3_to_mp4() { mp4tag.write_to_path(M4A_FILE).unwrap(); // reload the tag from the m4a file; this time specifying the tag type (you can also use `default()`) - let mp4tag_reload = Tag::with_tag_type(TagType::Mp4) + let mut mp4tag = Tag::with_tag_type(TagType::Mp4) .read_from_path(M4A_FILE) .unwrap(); // the tag originated from an mp3 file is successfully written to an m4a file! - assert_eq!(mp4tag_reload.title(), Some("title from mp3 file")); + assert_eq!(mp4tag.title(), Some("title from mp3 file")); + // multiple artists + mp4tag.add_artist("artist1 of mp4"); + mp4tag.add_artist("artist2 of mp4"); + assert_eq!( + mp4tag.artists(), + Some(vec!["artist1 of mp4", "artist2 of mp4"]) + ); + // convert to id3 tag, which does not support multiple artists + let mp3tag = mp4tag.into_tag(TagType::Id3v2); + assert_eq!(mp3tag.artist(), Some("artist1 of mp4;artist2 of mp4")); } diff --git a/tests/io.rs b/tests/io.rs index 378a2319..7a10b049 100644 --- a/tests/io.rs +++ b/tests/io.rs @@ -1,4 +1,5 @@ use audiotags::{MimeType, Picture, Tag}; +use beef::lean::Cow; macro_rules! test_file { ( $function:ident, $file:expr ) => { @@ -35,16 +36,16 @@ macro_rules! test_file { assert!(tags.album_artist().is_none()); tags.remove_album_artist(); - // let cover = Picture { - // mime_type: MimeType::Jpeg, - // data: vec![0u8; 10], - // }; + let cover = Picture { + mime_type: MimeType::Jpeg, + data: Cow::owned(vec![0u8; 10]), + }; - // tags.set_album_cover(cover.clone()); - // assert_eq!(tags.album_cover(), Some(cover)); - // tags.remove_album_cover(); - // assert!(tags.album_cover().is_none()); - // tags.remove_album_cover(); + tags.set_album_cover(cover.clone()); + assert_eq!(tags.album_cover(), Some(cover)); + tags.remove_album_cover(); + assert!(tags.album_cover().is_none()); + tags.remove_album_cover(); } }; }