vapor_parser/id3v1/
mod.rs

1use crate::{error, utils::ID3V1_HEADER_SIZE};
2use error::{Error, Result};
3
4#[derive(Debug, Clone)]
5pub struct ID3V1Tag {
6    buffer: [u8; ID3V1_HEADER_SIZE],
7}
8
9impl ID3V1Tag {
10    pub fn new(buffer: [u8; ID3V1_HEADER_SIZE]) -> Self {
11        Self { buffer }
12    }
13
14    pub fn title(&self) -> String {
15        String::from_utf8_lossy(&self.buffer[3..33])
16            .trim_end_matches(char::from(0))
17            .to_string()
18    }
19
20    pub fn artist(&self) -> String {
21        String::from_utf8_lossy(&self.buffer[33..63])
22            .trim_end_matches(char::from(0))
23            .to_string()
24    }
25
26    pub fn album(&self) -> String {
27        String::from_utf8_lossy(&self.buffer[63..93])
28            .trim_end_matches(char::from(0))
29            .to_string()
30    }
31
32    pub fn year(&self) -> String {
33        String::from_utf8_lossy(&self.buffer[93..97])
34            .trim_end_matches(char::from(0))
35            .to_string()
36    }
37
38    pub fn comment(&self) -> String {
39        String::from_utf8_lossy(&self.buffer[97..127])
40            .trim_end_matches(char::from(0))
41            .to_string()
42    }
43
44    pub fn track_index(&self) -> u8 {
45        self.buffer[126]
46    }
47
48    pub fn genre(&self) -> u8 {
49        self.buffer[127]
50    }
51}
52
53pub fn is_id3v1_tag(buffer: &[u8]) -> bool {
54    if buffer.len() < 3 {
55        return false;
56    }
57    return &buffer[0..3] == b"TAG";
58}
59
60pub fn decode(buffer: &[u8; ID3V1_HEADER_SIZE]) -> Result<ID3V1Tag> {
61    if buffer.len() < ID3V1_HEADER_SIZE {
62        return Err(Error::Id3v1BufferTooShort);
63    }
64
65    if !is_id3v1_tag(buffer) {
66        return Err(Error::Id3v1InvalidTag);
67    }
68
69    Ok(ID3V1Tag::new(buffer.clone()))
70}