vapor_parser/id3v1/
mod.rs1use 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}