1use byteorder::{ByteOrder, ReadBytesExt, WriteBytesExt};
2use std::io::{Error, Read, Write};
3
4#[repr(C)]
6#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd)]
7pub struct Version {
8 pub major: u16,
10 pub minor: u16,
12}
13
14impl Version {
15 pub const SIZE: usize = std::mem::size_of::<Self>();
17
18 pub const fn new(major: u16, minor: u16) -> Self {
20 Self { major, minor }
21 }
22
23 pub const fn major(&self) -> u16 {
25 self.major
26 }
27
28 pub const fn minor(&self) -> u16 {
30 self.minor
31 }
32
33 pub const fn swap_bytes(&self) -> Self {
35 Self {
36 major: self.major.swap_bytes(),
37 minor: self.minor.swap_bytes(),
38 }
39 }
40
41 pub fn read<E: ByteOrder>(reader: &mut dyn Read) -> Result<Self, Error> {
43 Ok(Self {
44 major: reader.read_u16::<E>()?,
45 minor: reader.read_u16::<E>()?,
46 })
47 }
48
49 pub fn write<E: ByteOrder>(self, writer: &mut dyn Write) -> Result<(), Error> {
51 writer.write_u16::<E>(self.major)?;
52 writer.write_u16::<E>(self.minor)?;
53
54 Ok(())
55 }
56}
57
58#[cfg(test)]
59mod tests {
60 use super::*;
61
62 #[test]
63 fn test_layout() {
64 assert_eq!(std::mem::size_of::<Version>(), 4);
65 }
66
67 #[test]
68 fn test_serialization_le() {
69 let mut buffer = vec![];
70 let version = Version::new(1, 2);
71 assert!(version.write::<crate::LE>(&mut buffer).is_ok());
72
73 let result = Version::read::<crate::LE>(&mut buffer.as_slice()).unwrap();
74 assert_eq!(version, result);
75 assert_eq!(result.major(), 1);
76 assert_eq!(result.minor(), 2);
77 }
78
79 #[test]
80 fn test_serialization_be() {
81 let mut buffer = vec![];
82 let version = Version::new(1, 2);
83 assert!(version.write::<crate::BE>(&mut buffer).is_ok());
84
85 let result = Version::read::<crate::BE>(&mut buffer.as_slice()).unwrap();
86 assert_eq!(version, result);
87 assert_eq!(result.major(), 1);
88 assert_eq!(result.minor(), 2);
89 }
90}