Skip to content

Commit d941df5

Browse files
committed
Add Mark and Space variants to Parity enum
1 parent 22d69ba commit d941df5

File tree

5 files changed

+65
-3
lines changed

5 files changed

+65
-3
lines changed

src/lib.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,16 @@ pub enum Parity {
208208

209209
/// Parity bit sets even number of 1 bits.
210210
Even,
211+
212+
/// Parity bit is set to 1.
213+
///
214+
/// Only supported on Windows and Linux.
215+
Mark,
216+
217+
/// Parity bit is set to 0.
218+
///
219+
/// Only supported on Windows and Linux.
220+
Space,
211221
}
212222

213223
impl fmt::Display for Parity {
@@ -216,6 +226,8 @@ impl fmt::Display for Parity {
216226
Parity::None => write!(f, "None"),
217227
Parity::Odd => write!(f, "Odd"),
218228
Parity::Even => write!(f, "Even"),
229+
Parity::Mark => write!(f, "Mark"),
230+
Parity::Space => write!(f, "Space"),
219231
}
220232
}
221233
}

src/posix/termios.rs

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,25 +145,71 @@ pub(crate) fn set_termios(fd: RawFd, termios: &Termios) -> Result<()> {
145145
crate::posix::ioctl::tcsets2(fd, termios)
146146
}
147147

148-
pub(crate) fn set_parity(termios: &mut Termios, parity: Parity) {
148+
// The Result return will seem pointless on platforms that support all parity variants, but we need
149+
// it for the others.
150+
#[allow(clippy::unnecessary_wraps)]
151+
pub(crate) fn set_parity(termios: &mut Termios, parity: Parity) -> Result<()> {
149152
match parity {
150153
Parity::None => {
151154
termios.c_cflag &= !(libc::PARENB | libc::PARODD);
152155
termios.c_iflag &= !libc::INPCK;
153156
termios.c_iflag |= libc::IGNPAR;
157+
#[cfg(any(target_os = "linux", target_os = "android"))]
158+
{
159+
termios.c_iflag &= !libc::CMSPAR;
160+
}
154161
}
155162
Parity::Odd => {
156163
termios.c_cflag |= libc::PARENB | libc::PARODD;
157164
termios.c_iflag |= libc::INPCK;
158165
termios.c_iflag &= !libc::IGNPAR;
166+
#[cfg(any(target_os = "linux", target_os = "android"))]
167+
{
168+
termios.c_iflag &= !libc::CMSPAR;
169+
}
159170
}
160171
Parity::Even => {
161172
termios.c_cflag &= !libc::PARODD;
162173
termios.c_cflag |= libc::PARENB;
163174
termios.c_iflag |= libc::INPCK;
164175
termios.c_iflag &= !libc::IGNPAR;
176+
#[cfg(any(target_os = "linux", target_os = "android"))]
177+
{
178+
termios.c_iflag &= !libc::CMSPAR;
179+
}
180+
}
181+
#[cfg(any(target_os = "linux", target_os = "android"))]
182+
Parity::Mark => {
183+
termios.c_cflag |= libc::PARODD;
184+
termios.c_cflag |= libc::PARENB;
185+
termios.c_iflag |= libc::INPCK;
186+
termios.c_iflag &= !libc::IGNPAR;
187+
termios.c_iflag |= libc::CMSPAR;
188+
}
189+
#[cfg(any(target_os = "linux", target_os = "android"))]
190+
Parity::Space => {
191+
termios.c_cflag &= !libc::PARODD;
192+
termios.c_cflag |= libc::PARENB;
193+
termios.c_iflag |= libc::INPCK;
194+
termios.c_iflag &= !libc::IGNPAR;
195+
termios.c_iflag |= libc::CMSPAR;
196+
}
197+
#[cfg(not(any(target_os = "linux", target_os = "android")))]
198+
Parity::Mark => {
199+
return Err(crate::Error::new(
200+
crate::ErrorKind::InvalidInput,
201+
"Mark parity not supported on this platform",
202+
));
203+
}
204+
#[cfg(not(any(target_os = "linux", target_os = "android")))]
205+
Parity::Space => {
206+
return Err(crate::Error::new(
207+
crate::ErrorKind::InvalidInput,
208+
"Space parity not supported on this platform",
209+
));
165210
}
166211
};
212+
Ok(())
167213
}
168214

169215
pub(crate) fn set_flow_control(termios: &mut Termios, flow_control: FlowControl) {

src/posix/tty.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ impl TTYPort {
171171

172172
// Configure the low-level port settings
173173
let mut termios = termios::get_termios(fd.0)?;
174-
termios::set_parity(&mut termios, builder.parity);
174+
termios::set_parity(&mut termios, builder.parity)?;
175175
termios::set_flow_control(&mut termios, builder.flow_control);
176176
termios::set_data_bits(&mut termios, builder.data_bits);
177177
termios::set_stop_bits(&mut termios, builder.stop_bits);
@@ -653,7 +653,7 @@ impl SerialPort for TTYPort {
653653

654654
fn set_parity(&mut self, parity: Parity) -> Result<()> {
655655
let mut termios = termios::get_termios(self.fd)?;
656-
termios::set_parity(&mut termios, parity);
656+
termios::set_parity(&mut termios, parity)?;
657657
#[cfg(any(target_os = "ios", target_os = "macos"))]
658658
return termios::set_termios(self.fd, &termios, self.baud_rate);
659659
#[cfg(not(any(target_os = "ios", target_os = "macos")))]

src/windows/com.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,8 @@ impl SerialPort for COMPort {
334334
match dcb.Parity {
335335
ODDPARITY => Ok(Parity::Odd),
336336
EVENPARITY => Ok(Parity::Even),
337+
MARKPARITY => Ok(Parity::Mark),
338+
SPACEPARITY => Ok(Parity::Space),
337339
NOPARITY => Ok(Parity::None),
338340
_ => Err(Error::new(
339341
ErrorKind::Unknown,

src/windows/dcb.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,8 @@ pub(crate) fn set_parity(dcb: &mut DCB, parity: Parity) {
8181
Parity::None => NOPARITY,
8282
Parity::Odd => ODDPARITY,
8383
Parity::Even => EVENPARITY,
84+
Parity::Mark => MARKPARITY,
85+
Parity::Space => SPACEPARITY,
8486
};
8587

8688
dcb.set_fParity(if parity == Parity::None { FALSE } else { TRUE } as DWORD);

0 commit comments

Comments
 (0)