#[allow(clippy::wildcard_imports)]
use crate::components::tags::*;
use crate::{Album, AnyTag, Picture, Result, TagType};
use std::borrow::Cow;
use std::fs::{File, OpenOptions};
pub trait AudioTag: AudioTagEdit + AudioTagWrite + ToAnyTag {}
pub trait AudioTagEdit {
fn title(&self) -> Option<&str>;
fn set_title(&mut self, title: &str);
fn remove_title(&mut self);
fn artist_str(&self) -> Option<&str>;
fn set_artist(&mut self, artist: &str);
fn artists_vec(&self) -> Option<Vec<&str>> {
self.artist_str().map(|a| a.split('/').collect())
}
fn remove_artist(&mut self);
fn date(&self) -> Option<String> {
self.year().map(|y| y.to_string())
}
fn set_date(&mut self, date: &str) {
if let Ok(d) = date.parse::<i32>() {
self.set_year(d)
}
}
fn remove_date(&mut self) {
self.remove_year()
}
fn year(&self) -> Option<i32>;
fn set_year(&mut self, year: i32);
fn remove_year(&mut self);
fn album(&self) -> Album<'_> {
Album {
title: self.album_title(),
artists: self.album_artists_vec(),
covers: self.album_covers(),
}
}
fn album_title(&self) -> Option<&str>;
fn set_album_title(&mut self, v: &str);
fn remove_album_title(&mut self);
fn album_artist_str(&self) -> Option<&str>;
fn album_artists_vec(&self) -> Option<Vec<&str>> {
self.album_artist_str().map(|a| a.split('/').collect())
}
fn set_album_artist(&mut self, artist: &str);
fn remove_album_artists(&mut self);
fn album_covers(&self) -> (Option<Picture>, Option<Picture>) {
(self.front_cover(), self.back_cover())
}
fn remove_album_covers(&mut self) {
self.remove_front_cover();
self.remove_back_cover();
}
fn front_cover(&self) -> Option<Picture>;
fn set_front_cover(&mut self, cover: Picture);
fn remove_front_cover(&mut self);
fn back_cover(&self) -> Option<Picture>;
fn set_back_cover(&mut self, cover: Picture);
fn remove_back_cover(&mut self);
fn pictures(&self) -> Option<Cow<'static, [Picture]>>;
fn track(&self) -> (Option<u32>, Option<u32>) {
(self.track_number(), self.total_tracks())
}
fn set_track(&mut self, track: u32) {
self.set_track_number(track);
}
fn remove_track(&mut self) {
self.remove_track_number();
self.remove_total_tracks();
}
fn track_number(&self) -> Option<u32>;
fn set_track_number(&mut self, track_number: u32);
fn remove_track_number(&mut self);
fn total_tracks(&self) -> Option<u32>;
fn set_total_tracks(&mut self, total_track: u32);
fn remove_total_tracks(&mut self);
fn disc(&self) -> (Option<u32>, Option<u32>) {
(self.disc_number(), self.total_discs())
}
fn remove_disc(&mut self) {
self.remove_disc_number();
self.remove_total_discs();
}
fn disc_number(&self) -> Option<u32>;
fn set_disc_number(&mut self, disc_number: u32);
fn remove_disc_number(&mut self);
fn total_discs(&self) -> Option<u32>;
fn set_total_discs(&mut self, total_discs: u32);
fn remove_total_discs(&mut self);
}
pub trait AudioTagWrite {
fn write_to(&self, file: &mut File) -> Result<()>;
fn write_to_path(&self, path: &str) -> Result<()> {
self.write_to(&mut OpenOptions::new().read(true).write(true).open(path)?)?;
Ok(())
}
}
pub trait ToAnyTag: ToAny {
fn to_anytag(&self) -> AnyTag<'_>;
fn to_dyn_tag(&self, tag_type: TagType) -> Box<dyn AudioTag> {
match tag_type {
#[cfg(feature = "format-ape")]
TagType::Ape => Box::new(ApeTag::from(self.to_anytag())),
#[cfg(feature = "format-id3")]
TagType::Id3v2(_) => Box::new(Id3v2Tag::from(self.to_anytag())),
#[cfg(feature = "format-mp4")]
TagType::Mp4 => Box::new(Mp4Tag::from(self.to_anytag())),
#[cfg(any(
feature = "format-vorbis",
feature = "format-flac",
feature = "format-opus"
))]
TagType::Vorbis(_) => Box::new(VorbisTag::from(self.to_anytag())),
#[cfg(feature = "format-riff")]
TagType::RiffInfo => Box::new(RiffTag::from(self.to_anytag())),
}
}
}
pub trait ToAny {
fn to_any(&self) -> &dyn std::any::Any;
#[allow(clippy::wrong_self_convention)]
fn to_any_mut(&mut self) -> &mut dyn std::any::Any;
}