Start work to use Album struct in AnyTag

Signed-off-by: Serial <69764315+Serial-ATA@users.noreply.github.com>
This commit is contained in:
Serial 2021-04-03 22:38:48 -04:00
parent c50e0edf67
commit 9950eea7fa
9 changed files with 274 additions and 157 deletions

View file

@ -1,6 +1,6 @@
use crate::{
impl_tag, AnyTag, AudioTag, AudioTagEdit, AudioTagWrite, Error, MimeType, Picture, Result,
TagType, ToAny, ToAnyTag,
impl_tag, Album, AnyTag, AudioTag, AudioTagEdit, AudioTagWrite, Error, MimeType, Picture,
Result, TagType, ToAny, ToAnyTag,
};
use std::{convert::TryInto, fs::File, path::Path};
@ -14,8 +14,8 @@ impl<'a> From<AnyTag<'a>> for FlacTag {
inp.title().map(|v| t.set_title(v));
inp.artists_as_string().map(|v| t.set_artist(&v));
inp.year.map(|v| t.set_year(v as u16));
inp.album_title().map(|v| t.set_album_title(v));
inp.album_artists_as_string().map(|v| t.set_artist(&v));
inp.album().title.map(|v| t.set_album_title(v));
inp.album().artists_as_string().map(|v| t.set_artist(&v));
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));
@ -30,9 +30,7 @@ impl<'a> From<&'a FlacTag> for AnyTag<'a> {
t.title = inp.title();
t.artists = inp.artists();
t.year = inp.year().map(|y| y as i32);
t.album = inp.album_title();
t.album_artists = inp.album_artists();
t.cover = inp.album_cover();
t.album = Album::new(inp.album_title(), inp.album_artists(), inp.album_cover());
t.track_number = inp.track_number();
t.total_tracks = inp.total_tracks();
t.disc_number = inp.disc_number();
@ -53,7 +51,10 @@ impl FlacTag {
None
}
}
pub fn set_value(&mut self, key: &str, val: &str) {
pub fn set_value<V>(&mut self, key: &str, val: V)
where
V: Into<String>,
{
self.0.vorbis_comments_mut().set(key, vec![val]);
}
pub fn remove(&mut self, k: &str) {
@ -79,8 +80,17 @@ impl AudioTagEdit for FlacTag {
fn set_artist(&mut self, artist: &str) {
self.set_value("ARTIST", artist)
}
fn add_artist(&mut self, artist: &str) {
todo!()
}
fn artists(&self) -> Option<Vec<&str>> {
todo!()
}
fn remove_artist(&mut self) {
self.remove("ARTIST");
self.remove("ARTIST")
}
fn year(&self) -> Option<u16> {
@ -104,6 +114,7 @@ impl AudioTagEdit for FlacTag {
self.remove("YEAR");
self.remove("DATE");
}
fn album_title(&self) -> Option<&str> {
self.get_value("ALBUM")
}
@ -115,16 +126,28 @@ impl AudioTagEdit for FlacTag {
self.remove("ALBUM");
}
fn album_artist(&self) -> Option<&str> {
self.get_value("ALBUMARTIST")
}
fn set_album_artist(&mut self, v: &str) {
self.set_value("ALBUMARTIST", v)
fn album_artists(&self) -> Option<Vec<&str>> {
if let Some(comments) = self.0.vorbis_comments() {
comments
.album_artist()
.map(|mut a| a.iter().map(|s| s as &str).collect())
} else {
None
}
}
fn remove_album_artist(&mut self) {
self.remove("ALBUMARTIST");
fn set_album_artists(&mut self, artists: String) {
self.set_value("ALBUMARTIST", artists)
}
fn add_album_artist(&mut self, artist: &str) {
todo!()
}
fn remove_album_artists(&mut self) {
self.remove("ALBUMARTIST")
}
fn album_cover(&self) -> Option<Picture> {
self.0
.pictures()
@ -150,6 +173,18 @@ impl AudioTagEdit for FlacTag {
.remove_picture_type(metaflac::block::PictureType::CoverFront)
}
fn track(&self) -> (Option<u16>, Option<u16>) {
todo!()
}
fn set_track(&mut self, track: u16) {
todo!()
}
fn remove_track(&mut self) {
todo!()
}
fn track_number(&self) -> Option<u16> {
if let Some(Ok(n)) = self.get_value("TRACKNUMBER").map(|x| x.parse::<u16>()) {
Some(n)
@ -178,6 +213,19 @@ impl AudioTagEdit for FlacTag {
fn remove_total_tracks(&mut self) {
self.remove("TOTALTRACKS");
}
fn disc(&self) -> (Option<u16>, Option<u16>) {
todo!()
}
fn set_disc(&mut self, disc: u16) {
todo!()
}
fn remove_disc(&mut self) {
todo!()
}
fn disc_number(&self) -> Option<u16> {
if let Some(Ok(n)) = self.get_value("DISCNUMBER").map(|x| x.parse::<u16>()) {
Some(n)

View file

@ -1,6 +1,6 @@
use crate::{
impl_tag, AnyTag, AudioTag, AudioTagEdit, AudioTagWrite, Error, MimeType, Picture, Result,
TagType, ToAny, ToAnyTag,
impl_tag, Album, AnyTag, AudioTag, AudioTagEdit, AudioTagWrite, Error, MimeType, Picture,
Result, TagType, ToAny, ToAnyTag,
};
use std::{convert::TryInto, fs::File, path::Path};
@ -14,9 +14,7 @@ impl<'a> From<&'a Id3v2Tag> for AnyTag<'a> {
title: inp.title(),
artists: inp.artists(),
year: inp.year().map(|y| y as i32),
album: inp.album_title(),
album_artists: inp.album_artists(),
cover: inp.album_cover(),
album: Album::new(inp.album_title(), inp.album_artists(), inp.album_cover()),
track_number: inp.track_number(),
total_tracks: inp.total_tracks(),
disc_number: inp.disc_number(),
@ -35,9 +33,10 @@ impl<'a> From<AnyTag<'a>> for Id3v2Tag {
inp.title().map(|v| tag.set_title(v));
inp.artists_as_string().map(|v| tag.set_artist(v.as_str()));
inp.year.map(|v| tag.set_year(v as u16));
inp.album_title().map(|v| tag.set_album_title(v));
inp.album_artists_as_string()
.map(|v| tag.set_album_artist(v.as_str()));
inp.album().title.map(|v| tag.set_album_title(v));
inp.album()
.artists
.map(|v| tag.set_album_artists(v.join(", ")));
inp.track_number().map(|v| tag.set_track(v as u16));
inp.total_tracks().map(|v| tag.set_total_tracks(v as u16));
inp.disc_number().map(|v| tag.set_disc(v as u16));
@ -76,11 +75,27 @@ impl AudioTagEdit for Id3v2Tag {
fn artist(&self) -> Option<&str> {
self.0.artist()
}
fn set_artist(&mut self, artist: &str) {
self.0.set_artist(artist)
}
fn add_artist(&mut self, artist: &str) {
if let Some(artists) = self.artist() {
let mut artists: Vec<&str> = artists.split(", ").collect();
artists.push(artist);
self.set_artist(&artists.join(", "))
} else {
self.set_artist(artist)
}
}
fn artists(&self) -> Option<Vec<&str>> {
todo!()
}
fn remove_artist(&mut self) {
self.0.remove_artist();
self.0.remove_artist()
}
fn year(&self) -> Option<u16> {
@ -103,14 +118,20 @@ impl AudioTagEdit for Id3v2Tag {
self.0.remove_album();
}
fn album_artist(&self) -> Option<&str> {
self.0.album_artist()
fn album_artists(&self) -> Option<Vec<&str>> {
self.0.album_artist().map(|a| a.split(", ").collect())
}
fn set_album_artist(&mut self, v: &str) {
self.0.set_album_artist(v)
fn set_album_artists(&mut self, artists: String) {
self.0.set_album_artist(artists)
}
fn remove_album_artist(&mut self) {
self.0.remove_album_artist();
fn add_album_artist(&mut self, artist: &str) {
todo!()
}
fn remove_album_artists(&mut self) {
self.0.remove_album_artist()
}
fn album_cover(&self) -> Option<Picture> {

View file

@ -1,6 +1,6 @@
use crate::{
impl_tag, AnyTag, AudioTag, AudioTagEdit, AudioTagWrite, Error, MimeType, Picture, Result,
TagType, ToAny, ToAnyTag,
impl_tag, Album, AnyTag, AudioTag, AudioTagEdit, AudioTagWrite, Error, MimeType, Picture,
Result, TagType, ToAny, ToAnyTag,
};
use std::{fs::File, path::Path};
@ -13,11 +13,7 @@ impl<'a> From<&'a Mp4Tag> for AnyTag<'a> {
let title = inp.title();
let artists = inp.artists().map(|i| i.into_iter().collect::<Vec<_>>());
let year = inp.year().map(|y| y as i32);
let album = inp.album_title();
let album_artists = inp
.album_artists()
.map(|i| i.into_iter().collect::<Vec<_>>());
let cover = inp.album_cover();
let album = Album::new(inp.album_title(), inp.album_artists(), inp.album_cover());
let (track_number, total_tracks) = inp.track();
let (disc_number, total_discs) = inp.disc();
@ -26,8 +22,6 @@ impl<'a> From<&'a Mp4Tag> for AnyTag<'a> {
artists,
year,
album,
cover,
album_artists,
track_number,
total_tracks,
disc_number,
@ -47,8 +41,9 @@ impl<'a> From<AnyTag<'a>> for Mp4Tag {
inp.artists()
.map(|i| i.iter().for_each(|&a| tag.add_artist(a)));
inp.year.map(|v| tag.set_year(v as u16));
inp.album_title().map(|v| tag.set_album_title(v));
inp.album_artists()
inp.album().title.map(|v| tag.set_album_title(v));
inp.album()
.artists
.map(|i| i.iter().for_each(|&a| tag.add_album_artist(a)));
inp.track_number().map(|v| tag.set_track_number(v));
inp.total_tracks().map(|v| tag.set_total_tracks(v));
@ -92,8 +87,9 @@ impl AudioTagEdit for Mp4Tag {
fn set_artist(&mut self, artist: &str) {
self.0.set_artist(artist)
}
fn remove_artist(&mut self) {
self.0.remove_artists();
fn add_artist(&mut self, artist: &str) {
self.0.add_artist(artist);
}
fn artists(&self) -> Option<Vec<&str>> {
@ -107,8 +103,8 @@ impl AudioTagEdit for Mp4Tag {
None
}
}
fn add_artist(&mut self, v: &str) {
self.0.add_artist(v);
fn remove_artist(&mut self) {
self.0.remove_artists();
}
fn year(&self) -> Option<u16> {
@ -132,30 +128,27 @@ impl AudioTagEdit for Mp4Tag {
self.0.remove_album();
}
fn album_artist(&self) -> Option<&str> {
self.0.album_artist()
}
fn set_album_artist(&mut self, v: &str) {
self.0.set_album_artist(v)
}
fn remove_album_artist(&mut self) {
self.0.remove_data(&FourCC(*b"aART"));
self.0.remove_album_artists();
}
fn album_artists(&self) -> Option<Vec<&str>> {
let v = self.0.album_artists().fold(Vec::new(), |mut v, a| {
v.push(a);
v
});
if v.len() > 0 {
Some(v)
let mut album_artists = self.0.album_artists().peekable();
if album_artists.peek().is_some() {
Some(album_artists.collect())
} else {
None
}
}
fn add_album_artist(&mut self, v: &str) {
self.0.add_album_artist(v);
fn set_album_artists(&mut self, artists: String) {
self.0.set_album_artist(artists)
}
fn add_album_artist(&mut self, artist: &str) {
self.0.add_album_artist(artist)
}
fn remove_album_artists(&mut self) {
self.0.remove_data(&FourCC(*b"aART"));
self.0.remove_album_artists();
}
fn album_cover(&self) -> Option<Picture> {
use mp4ameta::Data::*;

View file

@ -1,5 +1,5 @@
use crate::{
impl_tag, traits::MissingImplementations, AnyTag, AudioTag, AudioTagEdit, AudioTagWrite,
impl_tag, traits::MissingImplementations, Album, AnyTag, AudioTag, AudioTagEdit, AudioTagWrite,
Picture, Result, TagType, ToAny, ToAnyTag,
};
use std::{
@ -51,8 +51,10 @@ impl<'a> From<AnyTag<'a>> for OpusTag {
inp.title().map(|v| t.set_title(v));
inp.artists_as_string().map(|v| t.set_artist(&v));
inp.year.map(|v| t.set_year(v as u16));
inp.album_title().map(|v| t.set_album_title(v));
inp.album_artists_as_string().map(|v| t.set_artist(&v));
inp.album().title.map(|v| t.set_album_title(v));
inp.album()
.artists
.map(|v| t.set_album_artists(v.join(", ")));
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));
@ -67,9 +69,7 @@ impl<'a> From<&'a OpusTag> for AnyTag<'a> {
t.title = inp.title();
t.artists = inp.artists();
t.year = inp.year().map(|y| y as i32);
t.album = inp.album_title();
t.album_artists = inp.album_artists();
t.cover = inp.album_cover();
t.album = Album::new(inp.album_title(), inp.album_artists(), inp.album_cover());
t.track_number = inp.track_number();
t.total_tracks = inp.total_tracks();
t.disc_number = inp.disc_number();
@ -92,9 +92,12 @@ impl OpusTag {
None
}
}
pub fn set_value(&mut self, key: &str, val: &str) {
pub fn set_value<V>(&mut self, key: &str, val: V)
where
V: Into<String>,
{
let mut comments = self.0.comments.user_comments.clone();
let _ = comments.insert(key.to_string(), val.to_string());
let _ = comments.insert(key.to_string(), val.into());
self.0.comments.user_comments = comments;
}
pub fn remove(&mut self, key: &str) {
@ -122,6 +125,15 @@ impl AudioTagEdit for OpusTag {
fn set_artist(&mut self, artist: &str) {
self.set_value("ARTIST", artist)
}
fn add_artist(&mut self, artist: &str) {
todo!()
}
fn artists(&self) -> Option<Vec<&str>> {
todo!()
}
fn remove_artist(&mut self) {
self.remove("ARTIST");
}
@ -142,15 +154,14 @@ impl AudioTagEdit for OpusTag {
self.set_value("DATE", &year.to_string());
self.set_value("YEAR", &year.to_string());
}
fn remove_year(&mut self) {
self.remove("YEAR");
self.remove("DATE");
}
fn album_title(&self) -> Option<&str> {
self.get_value("ALBUM")
}
fn set_album_title(&mut self, title: &str) {
self.set_value("ALBUM", title)
}
@ -158,16 +169,21 @@ impl AudioTagEdit for OpusTag {
self.remove("ALBUM");
}
fn album_artist(&self) -> Option<&str> {
self.get_value("ALBUMARTIST")
fn album_artists(&self) -> Option<Vec<&str>> {
self.get_value("ALBUMARTIST").map(|a| vec![a])
}
fn set_album_artist(&mut self, v: &str) {
self.set_value("ALBUMARTIST", v)
fn set_album_artists(&mut self, artists: String) {
self.set_value("ALBUMARTIST", artists)
}
fn remove_album_artist(&mut self) {
fn add_album_artist(&mut self, artist: &str) {
todo!()
}
fn remove_album_artists(&mut self) {
self.remove("ALBUMARTIST");
}
fn album_cover(&self) -> Option<Picture> {
// TODO
// self.0
@ -182,7 +198,6 @@ impl AudioTagEdit for OpusTag {
// })
None
}
fn set_album_cover(&mut self, cover: Picture) {
// TODO
// self.remove_album_cover();
@ -207,10 +222,10 @@ impl AudioTagEdit for OpusTag {
fn set_track_number(&mut self, v: u16) {
self.set_value("TRACKNUMBER", &v.to_string())
}
fn remove_track_number(&mut self) {
self.remove("TRACKNUMBER");
}
// ! not standard
fn total_tracks(&self) -> Option<u16> {
if let Some(Ok(n)) = self.get_value("TOTALTRACKS").map(|x| x.parse::<u16>()) {
@ -225,6 +240,7 @@ impl AudioTagEdit for OpusTag {
fn remove_total_tracks(&mut self) {
self.remove("TOTALTRACKS");
}
fn disc_number(&self) -> Option<u16> {
if let Some(Ok(n)) = self.get_value("DISCNUMBER").map(|x| x.parse::<u16>()) {
Some(n)
@ -238,6 +254,7 @@ impl AudioTagEdit for OpusTag {
fn remove_disc_number(&mut self) {
self.remove("DISCNUMBER");
}
// ! not standard
fn total_discs(&self) -> Option<u16> {
if let Some(Ok(n)) = self.get_value("TOTALDISCS").map(|x| x.parse::<u16>()) {

View file

@ -1,6 +1,6 @@
use crate::{
impl_tag, traits::MissingImplementations, AnyTag, AudioTag, AudioTagEdit, AudioTagWrite, Error,
MimeType, Picture, Result, TagType, ToAny, ToAnyTag,
impl_tag, traits::MissingImplementations, Album, AnyTag, AudioTag, AudioTagEdit, AudioTagWrite,
Error, MimeType, Picture, Result, TagType, ToAny, ToAnyTag,
};
use std::{
collections::{hash_map::RandomState, HashMap},
@ -40,8 +40,9 @@ impl<'a> From<AnyTag<'a>> for VorbisTag {
inp.title().map(|v| t.set_title(v));
inp.artists_as_string().map(|v| t.set_artist(v.as_str()));
inp.year.map(|v| t.set_year(v as u16));
inp.album_title().map(|v| t.set_album_title(v));
inp.album_artists_as_string()
inp.album().title.map(|v| t.set_album_title(v));
inp.album()
.artists_as_string()
.map(|v| t.set_artist(v.as_str()));
inp.track_number().map(|v| t.set_track_number(v));
inp.total_tracks().map(|v| t.set_total_tracks(v));
@ -57,9 +58,7 @@ impl<'a> From<&'a VorbisTag> for AnyTag<'a> {
t.title = inp.title();
t.artists = inp.artists();
t.year = inp.year().map(|y| y as i32);
t.album = inp.album_title();
t.album_artists = inp.album_artists();
t.cover = inp.album_cover();
t.album = Album::new(inp.album_title(), inp.album_artists(), inp.album_cover());
t.track_number = inp.track_number();
t.total_tracks = inp.total_tracks();
t.disc_number = inp.disc_number();
@ -79,10 +78,13 @@ impl VorbisTag {
None
}
pub fn set_value(&mut self, key: &str, val: &str) {
pub fn set_value<V>(&mut self, key: &str, val: V)
where
V: Into<String>,
{
let mut comments: HashMap<String, String, RandomState> =
self.0.comment_list.clone().into_iter().collect();
let _ = comments.insert(key.to_string(), val.to_string());
let _ = comments.insert(key.to_string(), val.into());
self.0.comment_list = comments.into_iter().map(|a| a).collect();
}
@ -113,8 +115,24 @@ impl AudioTagEdit for VorbisTag {
fn set_artist(&mut self, artist: &str) {
self.set_value("ARTIST", artist)
}
fn add_artist(&mut self, artist: &str) {
let artists = if let Some(mut artists_existing) = self.artists() {
artists_existing.push(artist);
artists_existing
} else {
vec![artist]
};
self.set_value("ARTIST", artists.join(", "))
}
fn artists(&self) -> Option<Vec<&str>> {
self.artist().map(|a| a.split(", ").collect())
}
fn remove_artist(&mut self) {
self.remove("ARTIST");
self.remove("ARTIST")
}
fn year(&self) -> Option<u16> {
@ -149,14 +167,18 @@ impl AudioTagEdit for VorbisTag {
self.remove("ALBUM");
}
fn album_artist(&self) -> Option<&str> {
self.get_value("ALBUMARTIST")
fn album_artists(&self) -> Option<Vec<&str>> {
self.get_value("ALBUMARTIST").map(|a| vec![a])
}
fn set_album_artist(&mut self, v: &str) {
self.set_value("ALBUMARTIST", v)
fn set_album_artists(&mut self, artists: String) {
self.set_value("ALBUMARTIST", artists)
}
fn remove_album_artist(&mut self) {
fn add_album_artist(&mut self, artist: &str) {
todo!()
}
fn remove_album_artists(&mut self) {
self.remove("ALBUMARTIST");
}
// TODO

View file

@ -20,41 +20,31 @@ pub trait AudioTagEdit {
fn artist(&self) -> Option<&str>;
fn set_artist(&mut self, artist: &str);
fn remove_artist(&mut self);
fn add_artist(&mut self, artist: &str);
fn artists(&self) -> Option<Vec<&str>> {
self.artist().map(|v| vec![v])
}
fn add_artist(&mut self, artist: &str) {
self.set_artist(artist);
}
fn artists(&self) -> Option<Vec<&str>>;
fn remove_artist(&mut self);
fn year(&self) -> Option<u16>;
fn set_year(&mut self, year: u16);
fn remove_year(&mut self);
fn album(&self) -> Option<Album<'_>> {
self.album_title().map(|title| Album {
title,
artist: self.album_artist(),
fn album(&self) -> Album<'_> {
Album {
title: self.album_title(),
artists: self.album_artists(),
cover: self.album_cover(),
})
}
}
fn album_title(&self) -> Option<&str>;
fn set_album_title(&mut self, v: &str);
fn remove_album_title(&mut self);
fn album_artist(&self) -> Option<&str>;
fn set_album_artist(&mut self, v: &str);
fn remove_album_artist(&mut self);
fn album_artists(&self) -> Option<Vec<&str>> {
self.album_artist().map(|v| vec![v])
}
fn add_album_artist(&mut self, artist: &str) {
self.set_album_artist(artist);
}
fn album_artists(&self) -> Option<Vec<&str>>;
fn set_album_artists(&mut self, artists: String);
fn add_album_artist(&mut self, artist: &str);
fn remove_album_artists(&mut self);
fn album_cover(&self) -> Option<Picture>;
fn set_album_cover(&mut self, cover: Picture);

View file

@ -1,34 +1,65 @@
use super::picture::Picture;
/// A struct for representing an album for convenience.
#[derive(Debug)]
#[derive(Debug, Clone)]
pub struct Album<'a> {
pub title: &'a str,
pub artist: Option<&'a str>,
pub title: Option<&'a str>,
pub artists: Option<Vec<&'a str>>,
pub cover: Option<Picture<'a>>,
}
impl<'a> Album<'a> {
pub fn title(title: &'a str) -> Self {
impl<'a> Default for Album<'a> {
fn default() -> Self {
Self {
title,
artist: None,
title: None,
artists: None,
cover: None,
}
}
pub fn artist(mut self, artist: &'a str) -> Self {
self.artist = Some(artist);
}
impl<'a> Album<'a> {
pub fn new(
title: Option<&'a str>,
artists: Option<Vec<&'a str>>,
cover: Option<Picture<'a>>,
) -> Self {
Self {
title,
artists,
cover,
}
}
pub fn with_title(title: &'a str) -> Self {
Self {
title: Some(title),
artists: None,
cover: None,
}
}
pub fn set_artists(mut self, artists: Vec<&'a str>) -> Self {
self.artists = Some(artists);
self
}
pub fn cover(mut self, cover: Picture<'a>) -> Self {
pub fn append_artist(mut self, artist: &'a str) {
if let Some(mut artists) = self.artists {
artists.push(artist)
} else {
self.artists = Some(vec![artist])
}
}
pub fn set_cover(mut self, cover: Picture<'a>) -> Self {
self.cover = Some(cover);
self
}
pub fn full(title: &'a str, artist: &'a str, cover: Picture<'a>) -> Self {
Self {
title,
artist: Some(artist),
cover: Some(cover),
}
pub fn remove_artists(mut self) {
self.artists = None
}
pub fn remove_cover(mut self) {
self.cover = None
}
/// Turns `album` artists into a comma separated String
pub fn artists_as_string(&self) -> Option<String> {
self.artists.as_ref().map(|artists| artists.join(","))
}
}

View file

@ -1,12 +1,12 @@
use crate::Picture;
use crate::Album;
use std::borrow::Borrow;
/// The tag returned from `read_from_path`
#[derive(Default)]
pub struct AnyTag<'a> {
pub title: Option<&'a str>,
pub artists: Option<Vec<&'a str>>,
pub album: Option<&'a str>,
pub album_artists: Option<Vec<&'a str>>,
pub album: Album<'a>,
pub comments: Option<Vec<&'a str>>,
pub year: Option<i32>,
pub date: Option<&'a str>,
@ -14,7 +14,6 @@ pub struct AnyTag<'a> {
pub total_tracks: Option<u16>,
pub disc_number: Option<u16>,
pub total_discs: Option<u16>,
pub cover: Option<Picture<'a>>,
#[cfg(feature = "duration")]
pub duration_ms: Option<u32>,
}
@ -43,6 +42,14 @@ impl<'a> AnyTag<'a> {
a
});
}
/// Returns `album`
pub fn album(&self) -> Album {
self.album.clone()
}
/// Replaces `album`
pub fn set_album(&mut self, album: Album<'a>) {
self.album = album
}
/// Returns `year`
pub fn year(&self) -> Option<i32> {
self.year
@ -51,14 +58,6 @@ impl<'a> AnyTag<'a> {
pub fn set_year(&mut self, year: i32) {
self.year = Some(year);
}
/// Returns the name of `album`
pub fn album_title(&self) -> Option<&str> {
self.album.as_deref()
}
/// Returns the artists of `album`
pub fn album_artists(&self) -> Option<&[&str]> {
self.album_artists.as_deref()
}
/// Returns `track number`
pub fn track_number(&self) -> Option<u16> {
self.track_number
@ -85,10 +84,6 @@ impl<'a> AnyTag<'a> {
impl AnyTag<'_> {
/// Turns `artists` into a comma separated String
pub fn artists_as_string(&self) -> Option<String> {
self.artists().map(|artists| artists.join(","))
}
/// Turns `album` artists into a comma separated String
pub fn album_artists_as_string(&self) -> Option<String> {
self.album_artists().map(|artists| artists.join(","))
self.artists.as_ref().map(|artists| artists.join(","))
}
}

View file

@ -29,11 +29,11 @@ macro_rules! test_file {
assert!(tags.album_title().is_none());
tags.remove_album_title();
tags.set_album_artist("foo album artist");
assert_eq!(tags.album_artist(), Some("foo album artist"));
tags.remove_album_artist();
assert!(tags.album_artist().is_none());
tags.remove_album_artist();
tags.set_album_artists("foo album artist".to_string());
assert_eq!(tags.album_artists(), Some(vec!["foo album artist"]));
tags.remove_album_artists();
assert!(tags.album_artists().is_none());
tags.remove_album_artists();
// TODO
// let cover = Picture {
// mime_type: MimeType::Jpeg,