diff --git a/docs/audiotags.epub b/docs/audiotags.epub
index 7af99507..bdc78fc8 100644
Binary files a/docs/audiotags.epub and b/docs/audiotags.epub differ
diff --git a/docs/audiotags.pdf b/docs/audiotags.pdf
index a1503079..5e2dfa71 100644
Binary files a/docs/audiotags.pdf and b/docs/audiotags.pdf differ
diff --git a/docs/audiotags.tex b/docs/audiotags.tex
index 4a0e0641..04929ecd 100644
--- a/docs/audiotags.tex
+++ b/docs/audiotags.tex
@@ -205,7 +205,8 @@ The following example shows how you can read the tag in an \texttt{mp3} file, co
\CommentTok{// we have an mp3 and an m4a file}
\KeywordTok{const}\NormalTok{ MP3\_FILE}\OperatorTok{:} \OperatorTok{\&}\OtherTok{\textquotesingle{}static} \DataTypeTok{str} \OperatorTok{=} \StringTok{"assets/a.mp3"}\OperatorTok{;}
\KeywordTok{const}\NormalTok{ M4A\_FILE}\OperatorTok{:} \OperatorTok{\&}\OtherTok{\textquotesingle{}static} \DataTypeTok{str} \OperatorTok{=} \StringTok{"assets/a.m4a"}\OperatorTok{;}
- \CommentTok{// read tag from the mp3 file. Using \textasciigrave{}default()\textasciigrave{} so that the type of tag is guessed from the file extension}
+ \CommentTok{// read tag from the mp3 file. Using \textasciigrave{}default()\textasciigrave{} so that the}
+ \CommentTok{// type of tag is guessed from the file extension}
\KeywordTok{let} \KeywordTok{mut}\NormalTok{ mp3tag }\OperatorTok{=} \PreprocessorTok{Tag::}\KeywordTok{default}\NormalTok{()}\OperatorTok{.}\NormalTok{read\_from\_path(MP3\_FILE)}\OperatorTok{.}\NormalTok{unwrap()}\OperatorTok{;}
\CommentTok{// set the title}
\NormalTok{ mp3tag}\OperatorTok{.}\NormalTok{set\_title(}\StringTok{"title from mp3 file"}\NormalTok{)}\OperatorTok{;}
@@ -213,11 +214,13 @@ The following example shows how you can read the tag in an \texttt{mp3} file, co
\KeywordTok{let} \KeywordTok{mut}\NormalTok{ mp4tag }\OperatorTok{=}\NormalTok{ mp3tag}\OperatorTok{.}\NormalTok{into\_tag(}\PreprocessorTok{TagType::}\NormalTok{Mp4)}\OperatorTok{;}
\NormalTok{ mp4tag}\OperatorTok{.}\NormalTok{write\_to\_path(M4A\_FILE)}\OperatorTok{.}\NormalTok{unwrap()}\OperatorTok{;}
- \CommentTok{// reload the tag from the m4a file; this time specifying the tag type (you can also use \textasciigrave{}default()\textasciigrave{})}
+ \CommentTok{// reload the tag from the m4a file; this time specifying the}
+ \CommentTok{// tag type (you can also use \textasciigrave{}default()\textasciigrave{})}
\KeywordTok{let} \KeywordTok{mut}\NormalTok{ mp4tag }\OperatorTok{=} \PreprocessorTok{Tag::}\NormalTok{with\_tag\_type(}\PreprocessorTok{TagType::}\NormalTok{Mp4)}
\OperatorTok{.}\NormalTok{read\_from\_path(M4A\_FILE)}
\OperatorTok{.}\NormalTok{unwrap()}\OperatorTok{;}
- \CommentTok{// the tag originated from an mp3 file is successfully written to an m4a file!}
+ \CommentTok{// the tag originated from an mp3 file is successfully written}
+ \CommentTok{// to an m4a file!}
\PreprocessorTok{assert\_eq!}\NormalTok{(mp4tag}\OperatorTok{.}\NormalTok{title()}\OperatorTok{,} \ConstantTok{Some}\NormalTok{(}\StringTok{"title from mp3 file"}\NormalTok{))}\OperatorTok{;}
\CommentTok{// multiple artists}
\NormalTok{ mp4tag}\OperatorTok{.}\NormalTok{add\_artist(}\StringTok{"artist1 of mp4"}\NormalTok{)}\OperatorTok{;}
@@ -280,7 +283,9 @@ The following example shows how you can downcast a \texttt{Box\textless{}dyn\ Au
\OperatorTok{.}\NormalTok{expect(}\StringTok{"Fail to read!"}\NormalTok{)}\OperatorTok{;}
\PreprocessorTok{assert\_eq!}\NormalTok{(id3tag\_reload}\OperatorTok{.}\NormalTok{title()}\OperatorTok{,} \ConstantTok{Some}\NormalTok{(}\StringTok{"title from metaflac::Tag"}\NormalTok{))}\OperatorTok{;}
- \KeywordTok{let} \KeywordTok{mut}\NormalTok{ id3tag\_inner}\OperatorTok{:} \PreprocessorTok{id3::}\NormalTok{Tag }\OperatorTok{=} \PreprocessorTok{downcast!}\NormalTok{(id3tag\_reload}\OperatorTok{,}\NormalTok{ Id3v2Tag)}\OperatorTok{;}
+ \KeywordTok{let} \KeywordTok{mut}\NormalTok{ id3tag\_inner}\OperatorTok{:} \PreprocessorTok{id3::}\NormalTok{Tag }\OperatorTok{=}\NormalTok{ id3tag\_reload}\OperatorTok{.}\NormalTok{try\_into()}\OperatorTok{.}\NormalTok{unwrap()}\OperatorTok{;}
+ \CommentTok{// this would fail if \textasciigrave{}id3tag\_reload\textasciigrave{} isn\textquotesingle{}t really a id3 tag.}
+
\KeywordTok{let}\NormalTok{ timestamp }\OperatorTok{=} \PreprocessorTok{id3::}\NormalTok{Timestamp }\OperatorTok{\{}
\NormalTok{ year}\OperatorTok{:} \DecValTok{2013}\OperatorTok{,}
\NormalTok{ month}\OperatorTok{:} \ConstantTok{Some}\NormalTok{(}\DecValTok{2u8}\NormalTok{)}\OperatorTok{,}
@@ -294,7 +299,8 @@ The following example shows how you can downcast a \texttt{Box\textless{}dyn\ Au
\OperatorTok{.}\NormalTok{write\_to\_path(}\StringTok{"assets/a.mp3"}\OperatorTok{,} \PreprocessorTok{id3::Version::}\NormalTok{Id3v24)}
\OperatorTok{.}\NormalTok{expect(}\StringTok{"Fail to write!"}\NormalTok{)}\OperatorTok{;}
- \KeywordTok{let}\NormalTok{ id3tag\_reload }\OperatorTok{=} \PreprocessorTok{id3::Tag::}\NormalTok{read\_from\_path(}\StringTok{"assets/a.mp3"}\NormalTok{)}\OperatorTok{.}\NormalTok{expect(}\StringTok{"Fail to read!"}\NormalTok{)}\OperatorTok{;}
+ \KeywordTok{let}\NormalTok{ id3tag\_reload }\OperatorTok{=} \PreprocessorTok{id3::Tag::}\NormalTok{read\_from\_path(}\StringTok{"assets/a.mp3"}\NormalTok{)}
+ \OperatorTok{.}\NormalTok{expect(}\StringTok{"Fail to read!"}\NormalTok{)}\OperatorTok{;}
\PreprocessorTok{assert\_eq!}\NormalTok{(id3tag\_reload}\OperatorTok{.}\NormalTok{date\_recorded()}\OperatorTok{,} \ConstantTok{Some}\NormalTok{(timestamp))}\OperatorTok{;}
\OperatorTok{\}}
\end{Highlighting}
diff --git a/docs/conversion.html b/docs/conversion.html
index b4b556b4..79a137b8 100644
--- a/docs/conversion.html
+++ b/docs/conversion.html
@@ -171,33 +171,36 @@ code span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warni
// we have an mp3 and an m4a file
const MP3_FILE: &'static str = "assets/a.mp3";
const M4A_FILE: &'static str = "assets/a.m4a";
- // read tag from the mp3 file. Using `default()` so that the type of tag is guessed from the file extension
- let mut mp3tag = Tag::default().read_from_path(MP3_FILE).unwrap();
- // set the title
- mp3tag.set_title("title from mp3 file");
- // we can convert it to an mp4 tag and save it to an m4a file.
- let mut mp4tag = mp3tag.into_tag(TagType::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 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.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
- mp4tag.set_config(Config::default().sep_artist("/"));
- // separator is by default `;` but we can customise it
- let mp3tag = mp4tag.into_tag(TagType::Id3v2);
- assert_eq!(mp3tag.artist(), Some("artist1 of mp4/artist2 of mp4"));
-}
+ // read tag from the mp3 file. Using `default()` so that the
+ // type of tag is guessed from the file extension
+ let mut mp3tag = Tag::default().read_from_path(MP3_FILE).unwrap();
+ // set the title
+ mp3tag.set_title("title from mp3 file");
+ // we can convert it to an mp4 tag and save it to an m4a file.
+ let mut mp4tag = mp3tag.into_tag(TagType::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 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.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
+ mp4tag.set_config(Config::default().sep_artist("/"));
+ // separator is by default `;` but we can customise it
+ let mp3tag = mp4tag.into_tag(TagType::Id3v2);
+ assert_eq!(mp3tag.artist(), Some("artist1 of mp4/artist2 of mp4"));
+}
diff --git a/docs/downcast.html b/docs/downcast.html
index 24d7d49b..8bf90876 100644
--- a/docs/downcast.html
+++ b/docs/downcast.html
@@ -183,23 +183,26 @@ code span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warni
.expect("Fail to read!");
assert_eq!(id3tag_reload.title(), Some("title from metaflac::Tag"));
- let mut id3tag_inner: id3::Tag = downcast!(id3tag_reload, Id3v2Tag);
- let timestamp = id3::Timestamp {
- year: 2013,
- month: Some(2u8),
- day: Some(5u8),
- hour: Some(6u8),
- minute: None,
- second: None,
- };
- id3tag_inner.set_date_recorded(timestamp.clone());
- id3tag_inner
- .write_to_path("assets/a.mp3", id3::Version::Id3v24)
- .expect("Fail to write!");
-
- let id3tag_reload = id3::Tag::read_from_path("assets/a.mp3").expect("Fail to read!");
- assert_eq!(id3tag_reload.date_recorded(), Some(timestamp));
-}
+ let mut id3tag_inner: id3::Tag = id3tag_reload.try_into().unwrap();
+ // this would fail if `id3tag_reload` isn't really a id3 tag.
+
+ let timestamp = id3::Timestamp {
+ year: 2013,
+ month: Some(2u8),
+ day: Some(5u8),
+ hour: Some(6u8),
+ minute: None,
+ second: None,
+ };
+ id3tag_inner.set_date_recorded(timestamp.clone());
+ id3tag_inner
+ .write_to_path("assets/a.mp3", id3::Version::Id3v24)
+ .expect("Fail to write!");
+
+ let id3tag_reload = id3::Tag::read_from_path("assets/a.mp3")
+ .expect("Fail to read!");
+ assert_eq!(id3tag_reload.date_recorded(), Some(timestamp));
+}
diff --git a/docs/search_index.json b/docs/search_index.json
index cfcfe6ef..82a9ae91 100644
--- a/docs/search_index.json
+++ b/docs/search_index.json
@@ -1 +1 @@
-[["index.html", "audiotags Manual Preface", " audiotags Manual Tianyi Shi 2020-10-27 Preface Thank you for considering audiotags! Before you start, please let me introduce to you some great features of bookdown: use left and right arrow keys to navigate to the previous/next page click the “font” (big “A”) button on the top-left and change to a serif font if you happen to hate sans-serif fonts as I do. If you believe that serious stuff must be rendered by LaTeX as I do, there is a LaTex-rendered PDF for you to download (click the download button on the top) If you love to read on a Kindle, there is also an epub output (click the download button on the top). Examples in this manual If you want to run the examples in this book: clone the repo and navigate into it create src/main.rs all examples, unless otherwise specified, can be copied verbatim from this book to src/main.rs and run with cargo run (if you’re reading it online, the copy button wil show if you hover over a code block) "],["start-simple.html", "Chapter 1 Start Simple", " Chapter 1 Start Simple The following example shows how you can read an audio file, parse, set, and save its metadata: use audiotags::{MimeType, Picture, Tag, TagType}; const MP3_FILE: &'static str = "assets/a.mp3"; fn main() { // using `default()` so that the metadata format is guessed // (from the file extension) (in this case, Id3v2 tag is read) let mut tag = Tag::default().read_from_path(MP3_FILE).unwrap(); // You can also specify the metadata format (tag type): let _tag = Tag::with_tag_type(TagType::Id3v2) .read_from_path(MP3_FILE) .expect("Fail to read!"); tag.set_title("foo title"); assert_eq!(tag.title(), Some("foo title")); tag.remove_title(); assert!(tag.title().is_none()); tag.remove_title(); // trying to remove a field that's already empty won't hurt let cover = Picture { mime_type: MimeType::Jpeg, data: &vec![0u8; 10], }; tag.set_album_cover(cover.clone()); assert_eq!(tag.album_cover(), Some(cover)); tag.remove_album_cover(); assert!(tag.album_cover().is_none()); tag.remove_album_cover(); tag.save_to_path(MP3_FILE).expect("Fail to save"); // TASK: reload the file and prove the data have been saved } "],["conversion.html", "Chapter 2 Conversion", " Chapter 2 Conversion The following example shows how you can read the tag in an mp3 file, convert it into an mp4 tag, and write it to an m4a file. use audiotags::{Config, Tag, TagType}; fn main() { // we have an mp3 and an m4a file const MP3_FILE: &'static str = "assets/a.mp3"; const M4A_FILE: &'static str = "assets/a.m4a"; // read tag from the mp3 file. Using `default()` so that the type of tag is guessed from the file extension let mut mp3tag = Tag::default().read_from_path(MP3_FILE).unwrap(); // set the title mp3tag.set_title("title from mp3 file"); // we can convert it to an mp4 tag and save it to an m4a file. let mut mp4tag = mp3tag.into_tag(TagType::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 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.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 mp4tag.set_config(Config::default().sep_artist("/")); // separator is by default `;` but we can customise it let mp3tag = mp4tag.into_tag(TagType::Id3v2); assert_eq!(mp3tag.artist(), Some("artist1 of mp4/artist2 of mp4")); } "],["anytag.html", "Chapter 3 AnyTag", " Chapter 3 AnyTag The following example shows how you can create a “generic” AnyTag and convert it into a specific tag type. use audiotags::{AnyTag, AudioTagEdit, Id3v2Tag}; fn main() { let mut tag = AnyTag::default(); tag.set_title("foo"); tag.set_year(2001); let tag: Id3v2Tag = tag.into(); assert_eq!(tag.year(), Some(2001)); tag.write_to_path("assets/a.mp3").unwrap(); } "],["downcast.html", "Chapter 4 Downcast", " Chapter 4 Downcast The following example shows how you can downcast a Box<dyn AudioTag> into its “backend” tag type. This allows you to set the uncommon metadata supported by the corresponding backend but not by audiotags. use audiotags::*; fn main() { let mut innertag = metaflac::Tag::default(); innertag .vorbis_comments_mut() .set_title(vec!["title from metaflac::Tag"]); let tag: FlacTag = innertag.into(); let mut id3tag = tag.into_tag(TagType::Id3v2); id3tag .write_to_path("assets/a.mp3") .expect("Fail to write!"); let id3tag_reload = Tag::default() .read_from_path("assets/a.mp3") .expect("Fail to read!"); assert_eq!(id3tag_reload.title(), Some("title from metaflac::Tag")); let mut id3tag_inner: id3::Tag = downcast!(id3tag_reload, Id3v2Tag); let timestamp = id3::Timestamp { year: 2013, month: Some(2u8), day: Some(5u8), hour: Some(6u8), minute: None, second: None, }; id3tag_inner.set_date_recorded(timestamp.clone()); id3tag_inner .write_to_path("assets/a.mp3", id3::Version::Id3v24) .expect("Fail to write!"); let id3tag_reload = id3::Tag::read_from_path("assets/a.mp3").expect("Fail to read!"); assert_eq!(id3tag_reload.date_recorded(), Some(timestamp)); } "],["references.html", "References", " References "]]
+[["index.html", "audiotags Manual Preface", " audiotags Manual Tianyi Shi 2020-10-27 Preface Thank you for considering audiotags! Before you start, please let me introduce to you some great features of bookdown: use left and right arrow keys to navigate to the previous/next page click the “font” (big “A”) button on the top-left and change to a serif font if you happen to hate sans-serif fonts as I do. If you believe that serious stuff must be rendered by LaTeX as I do, there is a LaTex-rendered PDF for you to download (click the download button on the top) If you love to read on a Kindle, there is also an epub output (click the download button on the top). Examples in this manual If you want to run the examples in this book: clone the repo and navigate into it create src/main.rs all examples, unless otherwise specified, can be copied verbatim from this book to src/main.rs and run with cargo run (if you’re reading it online, the copy button wil show if you hover over a code block) "],["start-simple.html", "Chapter 1 Start Simple", " Chapter 1 Start Simple The following example shows how you can read an audio file, parse, set, and save its metadata: use audiotags::{MimeType, Picture, Tag, TagType}; const MP3_FILE: &'static str = "assets/a.mp3"; fn main() { // using `default()` so that the metadata format is guessed // (from the file extension) (in this case, Id3v2 tag is read) let mut tag = Tag::default().read_from_path(MP3_FILE).unwrap(); // You can also specify the metadata format (tag type): let _tag = Tag::with_tag_type(TagType::Id3v2) .read_from_path(MP3_FILE) .expect("Fail to read!"); tag.set_title("foo title"); assert_eq!(tag.title(), Some("foo title")); tag.remove_title(); assert!(tag.title().is_none()); tag.remove_title(); // trying to remove a field that's already empty won't hurt let cover = Picture { mime_type: MimeType::Jpeg, data: &vec![0u8; 10], }; tag.set_album_cover(cover.clone()); assert_eq!(tag.album_cover(), Some(cover)); tag.remove_album_cover(); assert!(tag.album_cover().is_none()); tag.remove_album_cover(); tag.save_to_path(MP3_FILE).expect("Fail to save"); // TASK: reload the file and prove the data have been saved } "],["conversion.html", "Chapter 2 Conversion", " Chapter 2 Conversion The following example shows how you can read the tag in an mp3 file, convert it into an mp4 tag, and write it to an m4a file. use audiotags::{Config, Tag, TagType}; fn main() { // we have an mp3 and an m4a file const MP3_FILE: &'static str = "assets/a.mp3"; const M4A_FILE: &'static str = "assets/a.m4a"; // read tag from the mp3 file. Using `default()` so that the // type of tag is guessed from the file extension let mut mp3tag = Tag::default().read_from_path(MP3_FILE).unwrap(); // set the title mp3tag.set_title("title from mp3 file"); // we can convert it to an mp4 tag and save it to an m4a file. let mut mp4tag = mp3tag.into_tag(TagType::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 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.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 mp4tag.set_config(Config::default().sep_artist("/")); // separator is by default `;` but we can customise it let mp3tag = mp4tag.into_tag(TagType::Id3v2); assert_eq!(mp3tag.artist(), Some("artist1 of mp4/artist2 of mp4")); } "],["anytag.html", "Chapter 3 AnyTag", " Chapter 3 AnyTag The following example shows how you can create a “generic” AnyTag and convert it into a specific tag type. use audiotags::{AnyTag, AudioTagEdit, Id3v2Tag}; fn main() { let mut tag = AnyTag::default(); tag.set_title("foo"); tag.set_year(2001); let tag: Id3v2Tag = tag.into(); assert_eq!(tag.year(), Some(2001)); tag.write_to_path("assets/a.mp3").unwrap(); } "],["downcast.html", "Chapter 4 Downcast", " Chapter 4 Downcast The following example shows how you can downcast a Box<dyn AudioTag> into its “backend” tag type. This allows you to set the uncommon metadata supported by the corresponding backend but not by audiotags. use audiotags::*; fn main() { let mut innertag = metaflac::Tag::default(); innertag .vorbis_comments_mut() .set_title(vec!["title from metaflac::Tag"]); let tag: FlacTag = innertag.into(); let mut id3tag = tag.into_tag(TagType::Id3v2); id3tag .write_to_path("assets/a.mp3") .expect("Fail to write!"); let id3tag_reload = Tag::default() .read_from_path("assets/a.mp3") .expect("Fail to read!"); assert_eq!(id3tag_reload.title(), Some("title from metaflac::Tag")); let mut id3tag_inner: id3::Tag = id3tag_reload.try_into().unwrap(); // this would fail if `id3tag_reload` isn't really a id3 tag. let timestamp = id3::Timestamp { year: 2013, month: Some(2u8), day: Some(5u8), hour: Some(6u8), minute: None, second: None, }; id3tag_inner.set_date_recorded(timestamp.clone()); id3tag_inner .write_to_path("assets/a.mp3", id3::Version::Id3v24) .expect("Fail to write!"); let id3tag_reload = id3::Tag::read_from_path("assets/a.mp3") .expect("Fail to read!"); assert_eq!(id3tag_reload.date_recorded(), Some(timestamp)); } "],["references.html", "References", " References "]]
diff --git a/src/traits.rs b/src/traits.rs
index da7fc769..588bea6e 100644
--- a/src/traits.rs
+++ b/src/traits.rs
@@ -142,6 +142,8 @@ pub trait IntoAnyTag {
/// Convert the tag type, which can be lossy.
fn into_tag(&self, tag_type: TagType) -> Box {
+ // TODO: write a macro or something that implement this method for every tag type so that if the
+ // TODO: target type is the same, just return self
match tag_type {
TagType::Id3v2 => Box::new(Id3v2Tag::from(self.into_anytag())),
TagType::Mp4 => Box::new(Mp4Tag::from(self.into_anytag())),