Skip to main content

mp4_atom/meta/ilst/
tool.rs

1use crate::*;
2
3#[derive(Debug, Clone, PartialEq, Eq)]
4#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
5pub struct Tool {
6    pub country_indicator: u16,
7    pub language_indicator: u16,
8    pub text: String,
9}
10
11impl Tool {
12    pub fn new(country_indicator: u16, language_indicator: u16, text: String) -> Result<Self> {
13        Ok(Self {
14            country_indicator,
15            language_indicator,
16            text,
17        })
18    }
19}
20
21impl Atom for Tool {
22    const KIND: FourCC = FourCC::new(b"\xa9too");
23
24    fn decode_body<B: Buf>(buf: &mut B) -> Result<Self> {
25        let data = super::data::decode_text(buf)?;
26        Ok(Tool {
27            country_indicator: data.country_indicator,
28            language_indicator: data.language_indicator,
29            text: data.text,
30        })
31    }
32
33    fn encode_body<B: BufMut>(&self, buf: &mut B) -> Result<()> {
34        super::data::encode_text(
35            self.country_indicator,
36            self.language_indicator,
37            &self.text,
38            buf,
39        )
40    }
41}
42
43#[cfg(test)]
44mod tests {
45    use super::*;
46
47    #[test]
48    fn test_ilst_tool_short_style() {
49        let buf = vec![
50            0, 0, 0, 28, 0xa9, b't', b'o', b'o', 0, 0, 0, 1, 0, 0, 0, 0, b'L', b'a', b'v', b'f',
51            b'6', b'1', b'.', b'7', b'.', b'1', b'0', b'0',
52        ];
53
54        let parse_result = Tool::decode(&mut buf.as_slice());
55        assert!(parse_result.is_ok());
56        let ctoo = parse_result.unwrap();
57        assert_eq!(ctoo.country_indicator, 0);
58        assert_eq!(ctoo.language_indicator, 0);
59        assert_eq!(ctoo.text, "Lavf61.7.100");
60    }
61
62    const ENCODED_CTOO: &[u8] = &[
63        0x00, 0x00, 0x00, 0x24, 0xA9, 0x74, 0x6F, 0x6F, 0x00, 0x00, 0x00, 0x1C, b'd', b'a', b't',
64        b'a', 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, b'L', b'a', b'v', b'f', b'6', b'1',
65        b'.', b'7', b'.', b'1', b'0', b'0',
66    ];
67
68    #[test]
69    fn test_ilst_tool_long_style() {
70        let inbuf: &mut std::io::Cursor<&&[u8]> = &mut std::io::Cursor::new(&ENCODED_CTOO);
71        let parse_result = Tool::decode(inbuf);
72        assert!(parse_result.is_ok());
73        let ctoo = parse_result.unwrap();
74        assert_eq!(ctoo.country_indicator, 0);
75        assert_eq!(ctoo.language_indicator, 0);
76        assert_eq!(ctoo.text, "Lavf61.7.100");
77
78        let mut outbuf = Vec::new();
79        ctoo.encode(&mut outbuf).unwrap();
80
81        assert_eq!(outbuf.as_slice(), ENCODED_CTOO);
82    }
83
84    #[test]
85    fn test_bad_nested_atom() {
86        let buf = vec![
87            0x00, 0x00, 0x00, 28, 0xA9, 0x74, 0x6F, 0x6F, 0x00, 0x00, 0x00, 0x1C, b'd', b'a', b't',
88            b'x', 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, b't', b'e', b's', b't',
89        ];
90
91        let parse_result = Tool::decode(&mut buf.as_slice());
92        assert!(parse_result.is_err());
93        match parse_result.err().unwrap() {
94            Error::UnexpectedBox(four_cc) => {
95                assert_eq!(four_cc, FourCC::new(b"datx"));
96            }
97            _ => {
98                panic!("unexpected error");
99            }
100        }
101    }
102
103    #[test]
104    fn test_bad_type_indicator() {
105        let buf = vec![
106            0x00, 0x00, 0x00, 28, 0xA9, 0x74, 0x6F, 0x6F, 0x00, 0x00, 0x00, 0x1C, b'd', b'a', b't',
107            b'a', 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, b't', b'e', b's', b't',
108        ];
109
110        let parse_result = Tool::decode(&mut buf.as_slice());
111        assert!(parse_result.is_err());
112        match parse_result.err().unwrap() {
113            Error::Unsupported(s) => {
114                assert_eq!(s, "Only UTF-8 text is supported in ilst data atoms")
115            }
116            _ => {
117                panic!("unexpected error");
118            }
119        }
120    }
121}