1use std::{fmt::Display, str::FromStr};
2
3use crate::error::ParseVersionError;
4
5#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd)]
8pub struct Version {
9 major: usize,
10 minor: usize,
11}
12
13impl Version {
14 pub const V1_0: Version = Version { major: 1, minor: 0 };
16
17 pub fn new(major: usize, minor: usize) -> Version {
19 Version { major, minor }
20 }
21
22 pub const fn latest() -> Version {
24 Version::V1_0
25 }
26
27 pub fn major(&self) -> usize {
29 self.major
30 }
31
32 pub fn minor(&self) -> usize {
34 self.minor
35 }
36}
37
38#[test]
39fn version_ordering() {
40 assert!(Version { major: 1, minor: 0 } < Version { major: 1, minor: 1 });
41 assert!(Version { major: 2, minor: 0 } > Version { major: 1, minor: 0 });
42}
43
44impl Default for Version {
45 fn default() -> Self {
46 Self::V1_0
47 }
48}
49
50impl Display for Version {
51 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
52 write!(f, "{}.{}", self.major, self.minor)
53 }
54}
55
56impl FromStr for Version {
57 type Err = ParseVersionError;
58
59 fn from_str(s: &str) -> Result<Self, Self::Err> {
60 let (major_part, minor_part) = s.split_once(".").ok_or(ParseVersionError::MissingDot)?;
61 let major: usize = major_part.parse::<usize>()?;
62 let minor: usize = minor_part.parse::<usize>()?;
63 Ok(Self { major, minor })
64 }
65}
66
67#[test]
68fn correct_version_from_str() {
69 assert_eq!(Version::from_str("1.0").unwrap(), Version::new(1, 0));
70 assert_eq!(Version::from_str("2.0").unwrap(), Version::new(2, 0));
71 assert_eq!(Version::from_str("2.20").unwrap(), Version::new(2, 20));
72}
73
74#[test]
75fn incorrect_version_from_str() {
76 assert!(matches!(
77 Version::from_str("1"),
78 Err(ParseVersionError::MissingDot)
79 ));
80 match Version::from_str("1.1.1") {
81 Err(ParseVersionError::ParseInt(_)) => {}
82 Ok(_) => panic!("'1.1.1' should not be a valid version"),
83 Err(_) => panic!("'1.1.1' should raise ParseIntError"),
84 }
85}
86
87#[derive(Clone, Debug, Eq, PartialEq)]
92pub enum Message<B = Box<[u8]>> {
93 GetInfo,
95 SetTck { period_ns: u32 },
98 Shift {
100 num_bits: u32,
102 tms: B,
105 tdi: B,
108 },
109}
110
111pub type OwnedMessage = Message<Box<[u8]>>;
112pub type BorrowedMessage<'a> = Message<&'a [u8]>;
113
114#[derive(Clone, Debug, Eq, PartialEq)]
117pub struct XvcInfo {
118 version: Version,
119 max_vector_len: u32,
120}
121
122impl XvcInfo {
123 pub fn new(version: Version, max_vector_len: u32) -> XvcInfo {
125 XvcInfo {
126 version,
127 max_vector_len,
128 }
129 }
130
131 pub fn version(&self) -> Version {
133 self.version
134 }
135
136 pub fn max_vector_len(&self) -> u32 {
138 self.max_vector_len
139 }
140}
141
142impl Default for XvcInfo {
143 fn default() -> XvcInfo {
144 XvcInfo {
145 version: Version::default(),
146 max_vector_len: 10 * 1024 * 1024, }
148 }
149}
150
151#[derive(Eq, PartialEq, Clone, Debug)]
153pub enum XvcCommand {
154 GetInfo,
155 SetTck,
156 Shift,
157}