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}