use std::{fmt, time::Duration};
pub mod extraction;
pub use extraction::extract_metadata;
#[derive(Debug, Clone, Default)]
pub struct Metadata {
pub title: Option<String>,
pub artist: Option<String>,
pub album: Option<String>,
pub year: Option<String>,
pub genre: Option<String>,
pub cover: Option<Vec<u8>>,
pub duration: Option<Duration>,
pub sample_rate: Option<u32>,
pub channels: Option<u8>,
pub has_tag: bool,
}
#[derive(Debug)]
pub enum MetadataError {
ReadError,
NoTag,
NoTitle,
NoArtist,
NoAlbum,
NoYear,
NoGenre,
NoCover,
NoDuration,
NoSampleRate,
NoChannels,
NoBitrate,
}
impl fmt::Display for Metadata {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.title.as_deref().unwrap_or(""))?;
write!(f, "{}", self.artist.as_deref().unwrap_or(""))?;
write!(f, "{}", self.album.as_deref().unwrap_or(""))?;
write!(f, "{}", self.year.as_deref().unwrap_or(""))?;
write!(f, "{}", self.genre.as_deref().unwrap_or(""))?;
Ok(())
}
}
impl fmt::Display for MetadataError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let text = match self {
MetadataError::ReadError => "Couldnt read file.",
MetadataError::NoTag => "File has no tag",
MetadataError::NoTitle => "Tag has no title",
MetadataError::NoArtist => "Tag has no artist",
MetadataError::NoAlbum => "Tag has no album",
MetadataError::NoYear => "Tag has no year",
MetadataError::NoGenre => "Tag has no genre",
MetadataError::NoCover => "Tag has no cover",
MetadataError::NoDuration => "Tag has no duration",
MetadataError::NoSampleRate => "Tag has no sample rate",
MetadataError::NoChannels => "Tag has no channels",
MetadataError::NoBitrate => "Tag has no bit rate",
};
write!(f, "{text}")
}
}
pub trait FormatDuration {
fn format(&self) -> String;
}
impl FormatDuration for Option<Duration> {
fn format(&self) -> String {
match self {
Some(duration) => {
let minutes = duration.as_secs() / 60;
let seconds = duration.as_secs() % 60;
format!("{:02}:{:02}", minutes, seconds)
}
None => "00:00".to_string(),
}
}
}