use crate::{error, utils::ID3V1_HEADER_SIZE};
use error::{Error, Result};
#[derive(Debug, Clone)]
pub struct ID3V1Tag {
buffer: [u8; ID3V1_HEADER_SIZE],
}
impl ID3V1Tag {
pub fn new(buffer: [u8; ID3V1_HEADER_SIZE]) -> Self {
Self { buffer }
}
pub fn title(&self) -> String {
String::from_utf8_lossy(&self.buffer[3..33])
.trim_end_matches(char::from(0))
.to_string()
}
pub fn artist(&self) -> String {
String::from_utf8_lossy(&self.buffer[33..63])
.trim_end_matches(char::from(0))
.to_string()
}
pub fn album(&self) -> String {
String::from_utf8_lossy(&self.buffer[63..93])
.trim_end_matches(char::from(0))
.to_string()
}
pub fn year(&self) -> String {
String::from_utf8_lossy(&self.buffer[93..97])
.trim_end_matches(char::from(0))
.to_string()
}
pub fn comment(&self) -> String {
String::from_utf8_lossy(&self.buffer[97..127])
.trim_end_matches(char::from(0))
.to_string()
}
pub fn track_index(&self) -> u8 {
self.buffer[126]
}
pub fn genre(&self) -> u8 {
self.buffer[127]
}
}
pub fn is_id3v1_tag(buffer: &[u8]) -> bool {
if buffer.len() < 3 {
return false;
}
return &buffer[0..3] == b"TAG";
}
pub fn decode(buffer: &[u8; ID3V1_HEADER_SIZE]) -> Result<ID3V1Tag> {
if buffer.len() < ID3V1_HEADER_SIZE {
return Err(Error::Id3v1BufferTooShort);
}
if !is_id3v1_tag(buffer) {
return Err(Error::Id3v1InvalidTag);
}
Ok(ID3V1Tag::new(buffer.clone()))
}