1use std::fmt;
2
3use crate::*;
4
5pub use num::rational::Ratio;
7pub use num::traits::ToBytes;
8
9#[derive(Clone, Copy, PartialEq, Eq, Hash)]
11#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
13pub struct FourCC([u8; 4]);
14
15impl FourCC {
16 pub const fn new(value: &[u8; 4]) -> Self {
19 FourCC(*value)
20 }
21}
22
23impl From<u32> for FourCC {
24 fn from(value: u32) -> Self {
25 FourCC(value.to_be_bytes())
26 }
27}
28
29impl From<FourCC> for u32 {
30 fn from(cc: FourCC) -> Self {
31 u32::from_be_bytes(cc.0)
32 }
33}
34
35impl From<[u8; 4]> for FourCC {
36 fn from(value: [u8; 4]) -> Self {
37 FourCC(value)
38 }
39}
40
41impl From<FourCC> for [u8; 4] {
42 fn from(cc: FourCC) -> Self {
43 cc.0
44 }
45}
46
47impl From<&[u8; 4]> for FourCC {
48 fn from(value: &[u8; 4]) -> Self {
49 FourCC(*value)
50 }
51}
52
53impl fmt::Display for FourCC {
54 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
55 let s = String::from_utf8_lossy(&self.0);
56 write!(f, "{s}")
57 }
58}
59
60impl fmt::Debug for FourCC {
61 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
62 let s = String::from_utf8_lossy(&self.0);
63 write!(f, "{s}")
64 }
65}
66
67impl Encode for FourCC {
68 fn encode<B: BufMut>(&self, buf: &mut B) -> Result<()> {
69 self.0.encode(buf)
70 }
71}
72
73impl Decode for FourCC {
74 fn decode<B: Buf>(buf: &mut B) -> Result<Self> {
75 Ok(FourCC(<[u8; 4]>::decode(buf)?))
76 }
77}
78
79impl AsRef<[u8; 4]> for FourCC {
80 fn as_ref(&self) -> &[u8; 4] {
81 &self.0
82 }
83}
84
85#[derive(Debug, Copy, Clone, Default, PartialEq, Eq)]
86#[allow(non_camel_case_types)]
87#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
88pub struct u24([u8; 3]);
89
90impl u24 {
91 pub const MAX: u32 = 0x00FF_FFFF;
92}
93
94impl From<[u8; 3]> for u24 {
95 fn from(value: [u8; 3]) -> Self {
96 Self(value)
97 }
98}
99
100impl Decode for u24 {
101 fn decode<B: Buf>(buf: &mut B) -> Result<Self> {
102 Ok(Self(<[u8; 3]>::decode(buf)?))
103 }
104}
105
106impl Encode for u24 {
107 fn encode<B: BufMut>(&self, buf: &mut B) -> Result<()> {
108 self.0.encode(buf)
109 }
110}
111
112impl From<u24> for u32 {
113 fn from(value: u24) -> Self {
114 u32::from_be_bytes([0, value.0[0], value.0[1], value.0[2]])
115 }
116}
117
118impl TryFrom<u32> for u24 {
119 type Error = std::array::TryFromSliceError;
120
121 fn try_from(value: u32) -> std::result::Result<Self, Self::Error> {
122 Ok(Self(value.to_be_bytes()[1..].try_into()?))
123 }
124}
125
126impl ToBytes for u24 {
127 type Bytes = [u8; 3];
128
129 fn to_be_bytes(&self) -> Self::Bytes {
130 self.0
131 }
132
133 fn to_le_bytes(&self) -> Self::Bytes {
134 [self.0[2], self.0[1], self.0[0]]
135 }
136}
137
138#[derive(Debug, Copy, Clone, Default, PartialEq, Eq)]
139#[allow(non_camel_case_types)]
140#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
141pub struct u48([u8; 6]);
142
143impl Decode for u48 {
144 fn decode<B: Buf>(buf: &mut B) -> Result<Self> {
145 Ok(Self(<[u8; 6]>::decode(buf)?))
146 }
147}
148
149impl Encode for u48 {
150 fn encode<B: BufMut>(&self, buf: &mut B) -> Result<()> {
151 self.0.encode(buf)
152 }
153}
154
155impl TryFrom<u64> for u48 {
156 type Error = std::array::TryFromSliceError;
157
158 fn try_from(value: u64) -> std::result::Result<Self, Self::Error> {
159 Ok(Self(value.to_be_bytes()[2..].try_into()?))
160 }
161}
162
163impl From<u48> for u64 {
164 fn from(value: u48) -> Self {
165 u64::from_be_bytes([
166 0, 0, value.0[0], value.0[1], value.0[2], value.0[3], value.0[4], value.0[5],
167 ])
168 }
169}
170
171impl From<[u8; 6]> for u48 {
172 fn from(value: [u8; 6]) -> Self {
173 u48(value)
174 }
175}
176
177impl AsRef<[u8; 6]> for u48 {
178 fn as_ref(&self) -> &[u8; 6] {
179 &self.0
180 }
181}
182
183#[derive(Copy, Clone, Default, PartialEq, Eq)]
186#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
187pub struct FixedPoint<T> {
188 int: T,
189 dec: T,
190}
191
192impl<T: Copy> FixedPoint<T> {
193 pub fn new(int: T, dec: T) -> Self {
194 Self { int, dec }
195 }
196
197 pub fn integer(&self) -> T {
198 self.int
199 }
200
201 pub fn decimal(&self) -> T {
202 self.dec
203 }
204}
205
206impl<T: Decode> Decode for FixedPoint<T> {
207 fn decode<B: Buf>(buf: &mut B) -> Result<Self> {
208 Ok(Self {
209 int: T::decode(buf)?,
210 dec: T::decode(buf)?,
211 })
212 }
213}
214
215impl<T: Encode> Encode for FixedPoint<T> {
216 fn encode<B: BufMut>(&self, buf: &mut B) -> Result<()> {
217 self.int.encode(buf)?;
218 self.dec.encode(buf)
219 }
220}
221
222impl<T: num::Zero> From<T> for FixedPoint<T> {
223 fn from(value: T) -> Self {
224 Self {
225 int: value,
226 dec: T::zero(),
227 }
228 }
229}
230
231impl<T> fmt::Debug for FixedPoint<T>
232where
233 T: num::Zero + fmt::Debug + PartialEq + Copy,
234 f64: From<T>,
235{
236 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
237 if self.dec.is_zero() {
238 write!(f, "{:?}", self.int)
239 } else {
240 let scale = 2f64.powi(8 * size_of::<T>() as i32);
242 let mut dec = f64::from(self.dec);
243 if dec < 0.0 {
244 dec += scale;
246 }
247 write!(f, "{:?}", f64::from(self.int) + dec / scale)
248 }
249 }
250}
251
252#[derive(Debug, Clone, PartialEq, Eq, Default)]
254#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
255pub struct Compressor(String);
256
257impl From<&str> for Compressor {
258 fn from(value: &str) -> Self {
259 Self(value.to_string())
260 }
261}
262
263impl From<String> for Compressor {
264 fn from(value: String) -> Self {
265 Self(value)
266 }
267}
268
269impl From<Compressor> for String {
270 fn from(value: Compressor) -> Self {
271 value.0
272 }
273}
274
275impl AsRef<str> for Compressor {
276 fn as_ref(&self) -> &str {
277 &self.0
278 }
279}
280
281impl Encode for Compressor {
282 fn encode<B: BufMut>(&self, buf: &mut B) -> Result<()> {
283 let name = self.0.as_bytes();
284 let len = name.len();
285 if len > 31 {
286 return Err(Error::InvalidSize);
287 }
288 (len as u8).encode(buf)?;
289 (&name[..len]).encode(buf)?;
290
291 let zero = [0u8; 31];
292 (&zero[..31 - len]).encode(buf)
293 }
294}
295
296impl Decode for Compressor {
297 fn decode<B: Buf>(buf: &mut B) -> Result<Self> {
298 let compressor_name_bytes = <[u8; 32]>::decode(buf)?;
299 match compressor_name_bytes[0] {
300 0 => Ok(Self(String::new())),
301 1..=31 => {
302 let start_bytes = 1;
303 let end_bytes = start_bytes + compressor_name_bytes[0] as usize;
304 let name = String::from_utf8_lossy(&compressor_name_bytes[start_bytes..end_bytes])
305 .trim_end_matches('\0')
306 .to_string();
307 Ok(Self(name))
308 }
309 _ => {
310 let name = String::from_utf8_lossy(&compressor_name_bytes)
312 .trim_end_matches('\0')
313 .to_string();
314 Ok(Self(name))
315 }
316 }
317 }
318}
319
320#[derive(Debug, Clone, PartialEq, Eq, Default)]
321#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
322pub struct Zeroed {
323 pub size: usize,
324}
325
326impl Zeroed {
327 pub fn new(size: usize) -> Self {
328 Self { size }
329 }
330}
331
332impl Encode for Zeroed {
333 fn encode<B: BufMut>(&self, buf: &mut B) -> Result<()> {
334 let zero = [0u8; 32];
335 let mut size = self.size;
336
337 while size > 0 {
338 let len = zero.len().min(size);
339 (&zero[..len]).encode(buf)?;
340 size -= len;
341 }
342
343 Ok(())
344 }
345}
346
347impl Decode for Zeroed {
348 fn decode<B: Buf>(buf: &mut B) -> Result<Self> {
349 let size = buf.remaining();
350 buf.advance(size);
351 Ok(Self { size })
352 }
353}
354
355impl From<usize> for Zeroed {
356 fn from(size: usize) -> Self {
357 Self { size }
358 }
359}
360
361#[derive(Copy, Clone, Default, PartialEq, Eq)]
363#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
364pub struct ExtendedType([u8; 16]);
365
366impl ExtendedType {
367 pub const fn new(value: &[u8; 16]) -> Self {
368 ExtendedType(*value)
369 }
370}
371
372impl From<&[u8; 16]> for ExtendedType {
373 fn from(val: &[u8; 16]) -> ExtendedType {
374 ExtendedType(*val)
375 }
376}
377
378impl From<[u8; 16]> for ExtendedType {
379 fn from(val: [u8; 16]) -> ExtendedType {
380 ExtendedType(val)
381 }
382}
383
384impl From<ExtendedType> for [u8; 16] {
385 fn from(et: ExtendedType) -> [u8; 16] {
386 et.0
387 }
388}
389
390impl Encode for ExtendedType {
391 fn encode<B: BufMut>(&self, buf: &mut B) -> Result<()> {
392 self.0.encode(buf)
393 }
394}
395impl Decode for ExtendedType {
396 fn decode<B: Buf>(buf: &mut B) -> Result<Self> {
397 Ok(ExtendedType(<[u8; 16]>::decode(buf)?))
398 }
399}
400
401impl fmt::Display for ExtendedType {
402 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
403 write!(f, "{:02x?}", self.0)
404 }
405}
406
407impl fmt::Debug for ExtendedType {
408 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
409 write!(f, "{:02x?}", self.0)
410 }
411}
412
413impl AsRef<[u8; 16]> for ExtendedType {
414 fn as_ref(&self) -> &[u8; 16] {
415 &self.0
416 }
417}
418
419#[cfg(test)]
420mod tests {
421 use crate::{Compressor, Decode as _, Encode as _, ExtendedType, FixedPoint};
422
423 #[test]
424 fn check_compressor_encode_minimal() {
425 let compressor = Compressor::from("A");
426 let mut buf = Vec::new();
427 compressor.encode(&mut buf).unwrap();
428 assert_eq!(buf.len(), 32);
429 assert_eq!(
430 buf,
431 vec![
432 0x01, b'A', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
433 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
434 0x00, 0x00, 0x00, 0x00,
435 ]
436 );
437 let decode = Compressor::decode(&mut buf.as_ref()).unwrap();
438 assert_eq!(decode, compressor);
439 }
440
441 #[test]
442 fn check_compressor_encode_empty() {
443 let compressor = Compressor::from("");
444 let mut buf = Vec::new();
445 compressor.encode(&mut buf).unwrap();
446 assert_eq!(buf.len(), 32);
447 assert_eq!(
448 buf,
449 vec![
450 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
451 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
452 0x00, 0x00, 0x00, 0x00,
453 ]
454 );
455 let decode = Compressor::decode(&mut buf.as_ref()).unwrap();
456 assert_eq!(decode, compressor);
457 }
458
459 #[test]
460 fn check_compressor_encode_maximal() {
461 let compressor = Compressor::from("ABCDEFGHIJKLMNOPQRSTUVWXYZabcde");
462 let mut buf = Vec::new();
463 compressor.encode(&mut buf).unwrap();
464 assert_eq!(buf.len(), 32);
465 assert_eq!(
466 buf,
467 vec![
468 0x1F, b'A', b'B', b'C', b'D', b'E', b'F', b'G', b'H', b'I', b'J', b'K', b'L', b'M',
469 b'N', b'O', b'P', b'Q', b'R', b'S', b'T', b'U', b'V', b'W', b'X', b'Y', b'Z', b'a',
470 b'b', b'c', b'd', b'e'
471 ]
472 );
473 let decode = Compressor::decode(&mut buf.as_ref()).unwrap();
474 assert_eq!(decode, compressor);
475 }
476
477 #[test]
478 fn check_compressor_encode_too_long() {
479 let compressor = Compressor::from("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdef");
480 let mut buf = Vec::new();
481 let result = compressor.encode(&mut buf);
482 assert!(result.is_err());
483 }
484
485 #[test]
486 fn fixed_point_debug_prints_the_value() {
487 assert_eq!(format!("{:?}", FixedPoint::new(1u16, 0)), "1");
489 assert_eq!(format!("{:?}", FixedPoint::new(1u16, 0x8000)), "1.5");
490 assert_eq!(format!("{:?}", FixedPoint::new(0u16, 0x4000)), "0.25");
491 assert_eq!(format!("{:?}", FixedPoint::new(0u8, 0x80)), "0.5");
493 assert_eq!(format!("{:?}", FixedPoint::new(-2i8, 0x40)), "-1.75");
495 assert_eq!(format!("{:?}", FixedPoint::new(-2i16, 0x4000)), "-1.75");
496 }
497
498 #[test]
499 fn test_extended_type_creation_and_conversion() {
500 let bytes: [u8; 16] = [
501 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d,
502 0x0e, 0x0f,
503 ];
504
505 let et_new = ExtendedType::new(&bytes);
506 let et_from = ExtendedType::from(bytes);
507 let et_ref_from = ExtendedType::from(&bytes);
508
509 assert_eq!(et_new, et_from);
510 assert_eq!(et_from, et_ref_from);
511
512 let output = <[u8; 16]>::from(et_new);
513
514 assert_eq!(bytes, output);
515 }
516}