vapor-parser 0.1.0

A parser for MPEG files
Documentation
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()))
}