From 5a190e48905cd4cf87dac9f99238c7c85d2cb28c Mon Sep 17 00:00:00 2001 From: Vladan Popovic Date: Tue, 21 Jun 2022 00:37:15 +0200 Subject: [PATCH] move read_line to IterableRx, improve read_response --- src/modem.rs | 49 ++++++++++++++++++++++++++++--------------------- 1 file changed, 28 insertions(+), 21 deletions(-) diff --git a/src/modem.rs b/src/modem.rs index a69989e..7fabae3 100644 --- a/src/modem.rs +++ b/src/modem.rs @@ -20,6 +20,7 @@ pub enum ModemError { CommandError(String), SetupError(String), SendDataError, + ReadError, TimeoutError, } @@ -46,6 +47,26 @@ impl IterableRx { println!("clearing serial rx"); self.reset(Duration::from_millis(500)).for_each(drop); } + + /// Reads a whole line (that ends with \\n) within the given `timeout` passed on input. + fn read_line(&mut self, timeout: Duration) -> Result { + let mut line: String = self.reset(timeout) + .map(|b| char::from(b)) + .take_while(|c| *c != '\n') + .collect(); + + // \r must come right before \n on read; take_while excludes the matched element. + if line.ends_with('\r') { + line.push('\n'); + Ok(line) + } + else if self.timeout.as_millis() == 0 { + Err(ModemError::TimeoutError) + } + else { + Err(ModemError::ReadError) + } + } } impl Iterator for IterableRx { @@ -117,15 +138,6 @@ impl Modem { Ok(()) } - /// Reads a whole line (that ends with \\n) within the given `timeout` passed on input. - /// - fn read_line(&mut self, timeout: Duration) -> String { - self.rx.reset(timeout) - .map(|b| char::from(b)) - .take_while(|c| *c != '\n') - .collect() - } - /// Reads the serial RX until a \\n char is encoutered, or a timeout is reached. The timeout is /// provided on input via the `timeout` argument. The first argument `contains` is checked /// against a line in the response, if it's there the reading stops. @@ -138,19 +150,14 @@ impl Modem { let match_text: String = contains.unwrap_or("\n".to_string()); loop { - let line = self.read_line(timeout.saturating_sub(start.elapsed())); - if line != "" { - println!("Read {} bytes from serial ({})", line.len(), line); - response.push_str(&line); - if line.contains("ERROR") || line.contains(&match_text) { - println!("Found match {} for line {} ; exiting response reader now ...", match_text, line); - println!("-----------------------------------------------------------"); - break Ok(response.to_string()) - } - } else { + let timeout = timeout - start.elapsed(); + let line = self.rx.read_line(timeout)?; + print!("Read {} bytes from serial: {}", line.len(), line); + response.push_str(&line); + if line.contains("ERROR") || line.contains(&match_text) { + println!("Found match {} for line {} ; exiting response reader now ...", match_text, line); println!("-----------------------------------------------------------"); - println!("got empty line from read_line :("); - break Err(ModemError::TimeoutError) + break Ok(response.to_string()) } } }