mirror of
https://github.com/laanwj/k210-sdk-stuff.git
synced 2024-11-22 01:16:20 +04:00
rust: esp8266at: Wrap parsing of responses to avoid exposing dependency on nom
Makes it possible to switch parser later for whatever reason, it's undesirable to expose these implementation details to clients.
This commit is contained in:
parent
d20791330d
commit
610af76592
@ -2,7 +2,7 @@ use std::fs::File;
|
||||
use std::io::BufRead;
|
||||
use std::io::BufReader;
|
||||
|
||||
use esp8266at::response::parse_response;
|
||||
use esp8266at::response::{parse,ParseResult};
|
||||
|
||||
fn main() {
|
||||
let f = File::open("data/parses.txt").unwrap();
|
||||
@ -13,14 +13,16 @@ fn main() {
|
||||
let mut lb = l[2..].as_bytes().to_vec();
|
||||
lb.push(13);
|
||||
lb.push(10);
|
||||
let res = parse_response(&lb);
|
||||
let res = parse(&lb);
|
||||
match res {
|
||||
Err(x) => {
|
||||
ParseResult::Err => {
|
||||
println!("failed command was: {}", l);
|
||||
println!("{:?}", x);
|
||||
}
|
||||
Ok((res, x)) => {
|
||||
if res.is_empty() {
|
||||
ParseResult::Incomplete => {
|
||||
println!("incomplete command was: {}", l);
|
||||
}
|
||||
ParseResult::Ok(res, x) => {
|
||||
if res == lb.len() {
|
||||
println!("{:?}", x);
|
||||
} else {
|
||||
println!("non-empty residue command was: {}", l);
|
||||
|
@ -1,10 +1,9 @@
|
||||
/** Example synchronous serial receive event loop (for std) */
|
||||
use nom::Offset;
|
||||
use std::fmt;
|
||||
use std::io;
|
||||
|
||||
use crate::handler::{NetworkEvent, SerialNetworkHandler};
|
||||
use crate::response::parse_response;
|
||||
use crate::response::{parse, ParseResult};
|
||||
|
||||
/** Mainloop handling serial input and dispatching network events */
|
||||
pub fn mainloop<P, F, X>(
|
||||
@ -34,24 +33,24 @@ where
|
||||
while start < ofs {
|
||||
// try parsing
|
||||
let tail = &serial_buf[start..ofs];
|
||||
let erase = match parse_response(tail) {
|
||||
Ok((residue, resp)) => {
|
||||
let erase = match parse(tail) {
|
||||
ParseResult::Ok(offset, resp) => {
|
||||
h.message(
|
||||
&resp,
|
||||
&mut |a, b, debug| {
|
||||
|a, b, debug| {
|
||||
running = f(a, b, debug);
|
||||
},
|
||||
debug,
|
||||
)?;
|
||||
|
||||
tail.offset(residue)
|
||||
offset
|
||||
}
|
||||
Err(nom::Err::Incomplete(_)) => {
|
||||
ParseResult::Incomplete => {
|
||||
// Incomplete, ignored, just retry after a new receive
|
||||
0
|
||||
}
|
||||
Err(err) => {
|
||||
writeln!(debug, "err: {:?}", err).unwrap();
|
||||
ParseResult::Err => {
|
||||
writeln!(debug, "err: {:?}", tail).unwrap();
|
||||
// Erase unparseable data to next line, if line is complete
|
||||
if let Some(ofs) = tail.iter().position(|&x| x == b'\n') {
|
||||
ofs + 1
|
||||
|
@ -1,6 +1,6 @@
|
||||
use core::str;
|
||||
/** Parser for ESP8266 AT responses */
|
||||
use nom::{digit, hex_digit};
|
||||
use core::str;
|
||||
use nom::{Offset, digit, hex_digit};
|
||||
|
||||
/** Connection type for CIPSTATUS etc */
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||
@ -73,6 +73,13 @@ pub enum Response<'a> {
|
||||
RecvPrompt,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub enum ParseResult<'a> {
|
||||
Ok(usize, Response<'a>),
|
||||
Incomplete,
|
||||
Err,
|
||||
}
|
||||
|
||||
/* Decimal unsigned integer */
|
||||
named!(num_u32<&[u8], u32>,
|
||||
// The unwrap() here is safe because digit will never return non-UTF8
|
||||
@ -279,7 +286,7 @@ named!(ipd_data<&[u8],Response>,
|
||||
);
|
||||
|
||||
/* Parse response from line */
|
||||
named!(pub parse_response<&[u8],Response>,
|
||||
named!(parse_response<&[u8],Response>,
|
||||
alt!(
|
||||
nl_terminated
|
||||
| ipd_data
|
||||
@ -288,6 +295,14 @@ named!(pub parse_response<&[u8],Response>,
|
||||
)
|
||||
);
|
||||
|
||||
pub fn parse(response: &[u8]) -> ParseResult {
|
||||
match parse_response(response) {
|
||||
Ok((residue, resp)) => ParseResult::Ok(response.offset(residue), resp),
|
||||
Err(nom::Err::Incomplete(_)) => ParseResult::Incomplete,
|
||||
Err(_) => ParseResult::Err,
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
@ -13,4 +13,3 @@ riscv = "0.5"
|
||||
k210-shared = { path = "../k210-shared" }
|
||||
k210-console = { path = "../k210-console" }
|
||||
esp8266at = { path = "../esp8266at", default-features = false }
|
||||
nom = { version = "4", default-features = false }
|
||||
|
@ -7,7 +7,7 @@
|
||||
use core::str;
|
||||
use embedded_hal::serial;
|
||||
use esp8266at::handler::{NetworkEvent, SerialNetworkHandler};
|
||||
use esp8266at::response::{parse_response, ConnectionType};
|
||||
use esp8266at::response::{parse, ConnectionType, ParseResult};
|
||||
use esp8266at::traits::{self, Write};
|
||||
use k210_hal::pac;
|
||||
use k210_hal::prelude::*;
|
||||
@ -21,7 +21,6 @@ use k210_shared::soc::sleep::usleep;
|
||||
use k210_shared::soc::spi::SPIExt;
|
||||
use k210_shared::soc::sysctl;
|
||||
use nb::block;
|
||||
use nom::Offset;
|
||||
use riscv::register::mcycle;
|
||||
use riscv_rt::entry;
|
||||
use k210_console::console::{Console, ScreenImage, DISP_HEIGHT, DISP_WIDTH};
|
||||
@ -159,8 +158,8 @@ fn main() -> ! {
|
||||
while start < ofs {
|
||||
// try parsing
|
||||
let tail = &serial_buf[start..ofs];
|
||||
let erase = match parse_response(tail) {
|
||||
Ok((residue, resp)) => {
|
||||
let erase = match parse(tail) {
|
||||
ParseResult::Ok(offset, resp) => {
|
||||
sh.message(&resp, |port, ev, _debug| {
|
||||
match ev {
|
||||
NetworkEvent::Ready => {
|
||||
@ -195,17 +194,17 @@ fn main() -> ! {
|
||||
}
|
||||
}, &mut debug).unwrap();
|
||||
|
||||
tail.offset(residue)
|
||||
offset
|
||||
}
|
||||
Err(nom::Err::Incomplete(_)) => {
|
||||
ParseResult::Incomplete => {
|
||||
// Incomplete, ignored, just retry after a new receive
|
||||
0
|
||||
}
|
||||
Err(err) => {
|
||||
ParseResult::Err => {
|
||||
if tail.len() > 100 {
|
||||
writeln!(debug, "err: Error([too long ...])").unwrap();
|
||||
} else {
|
||||
writeln!(debug, "err: {:?}", err).unwrap();
|
||||
writeln!(debug, "err: {:?}", tail).unwrap();
|
||||
}
|
||||
// Erase unparseable data to next line, if line is complete
|
||||
if let Some(ofs) = tail.iter().position(|&x| x == b'\n') {
|
||||
|
Loading…
Reference in New Issue
Block a user