1mod usb_conn;
15mod usb_info;
16mod usb_sync;
17
18#[cfg(feature = "serialport")]
19mod ser_cdc;
20#[cfg(feature = "serialport")]
21pub use ser_cdc::*;
22
23pub type Error = std::io::Error;
25
26pub mod usb {
33 pub use crate::usb_conn::*;
34 pub use crate::usb_info::*;
35 pub use crate::usb_sync::*;
36 pub use crate::Error;
37
38 #[inline(always)]
42 pub(crate) fn jerr(err: jni_min_helper::jni::errors::Error) -> Error {
43 use jni::errors::Error::*;
44 use jni_min_helper::*;
45 if let JavaException = err {
46 let err = jni_clear_ex(err);
47 if let Some(ex) = jni_last_cleared_ex() {
48 jni_with_env(|env| Ok((ex.get_class_name(env)?, ex.get_throwable_msg(env)?)))
49 .map(|(cls, msg)| Error::other(format!("{cls}: {msg}")))
50 .unwrap_or(Error::other(err))
51 } else {
52 Error::other(err)
53 }
54 } else {
55 Error::other(err)
56 }
57 }
58}
59
60#[cfg(feature = "serialport")]
61use nusb::transfer::{Queue, RequestBuffer};
62
63#[cfg(feature = "serialport")]
68pub trait UsbSerial: serialport::SerialPort {
69 fn configure(&mut self, conf: &SerialConfig) -> std::io::Result<()>;
71
72 fn into_queues(self) -> (Queue<RequestBuffer>, Queue<Vec<u8>>);
75
76 #[doc(hidden)]
77 fn sealer(_: private::Internal);
78}
79
80#[cfg(feature = "serialport")]
81use serialport::{DataBits, Parity, StopBits};
82
83#[cfg(feature = "serialport")]
85#[derive(Debug, Copy, Clone, PartialEq, Eq)]
86pub struct SerialConfig {
87 pub baud_rate: u32,
88 pub parity: Parity,
89 pub data_bits: DataBits,
90 pub stop_bits: StopBits,
91}
92
93#[cfg(feature = "serialport")]
94impl Default for SerialConfig {
95 fn default() -> Self {
96 Self {
97 baud_rate: 9600,
98 parity: Parity::None,
99 data_bits: DataBits::Eight,
100 stop_bits: StopBits::One,
101 }
102 }
103}
104
105#[cfg(feature = "serialport")]
106impl std::str::FromStr for SerialConfig {
107 type Err = Error;
108
109 fn from_str(s: &str) -> Result<Self, Self::Err> {
110 let bad_par = std::io::ErrorKind::InvalidInput;
111 let mut strs = s.split(',');
112
113 let str_baud = strs.next().ok_or(Error::new(bad_par, s))?;
114 let baud_rate = str_baud
115 .trim()
116 .parse()
117 .map_err(|_| Error::new(bad_par, s))?;
118
119 let str_parity = strs.next().ok_or(Error::new(bad_par, s))?;
120 let parity = match str_parity
121 .trim()
122 .chars()
123 .next()
124 .ok_or(Error::new(bad_par, s))?
125 {
126 'N' => Parity::None,
127 'O' => Parity::Odd,
128 'E' => Parity::Even,
129 _ => return Err(Error::new(bad_par, s)),
130 };
131
132 let str_data_bits = strs.next().ok_or(Error::new(bad_par, s))?;
133 let data_bits = str_data_bits
134 .trim()
135 .parse()
136 .map_err(|_| Error::new(bad_par, s))?;
137 let data_bits = match data_bits {
138 5 => DataBits::Five,
139 6 => DataBits::Six,
140 7 => DataBits::Seven,
141 8 => DataBits::Eight,
142 _ => return Err(Error::new(bad_par, s)),
143 };
144
145 let str_stop_bits = strs.next().ok_or(Error::new(bad_par, s))?;
146 let stop_bits = str_stop_bits
147 .trim()
148 .parse()
149 .map_err(|_| Error::new(bad_par, s))?;
150 let stop_bits = match stop_bits {
151 1. => StopBits::One,
152 2. => StopBits::Two,
153 _ => return Err(Error::new(bad_par, s)),
154 };
155
156 Ok(Self {
157 baud_rate,
158 parity,
159 data_bits,
160 stop_bits,
161 })
162 }
163}
164
165#[cfg(feature = "serialport")]
166impl std::fmt::Display for SerialConfig {
167 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
168 let baud_rate = self.baud_rate;
169 let parity = match self.parity {
170 Parity::None => 'N',
171 Parity::Odd => 'O',
172 Parity::Even => 'E',
173 };
174 let data_bits = match self.data_bits {
175 DataBits::Five => "5",
176 DataBits::Six => "6",
177 DataBits::Seven => "7",
178 DataBits::Eight => "8",
179 };
180 let stop_bits = match self.stop_bits {
181 StopBits::One => "1",
182 StopBits::Two => "2",
183 };
184 write!(f, "{baud_rate},{parity},{data_bits},{stop_bits}")
185 }
186}
187
188#[allow(unused)]
189mod private {
190 #[derive(Debug)]
192 pub struct Internal;
193}