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