thermostat/src/session.rs

91 lines
1.9 KiB
Rust
Raw Normal View History

2020-03-14 06:39:22 +08:00
use super::command_parser::{Command, Error as ParserError};
const MAX_LINE_LEN: usize = 64;
struct LineReader {
buf: [u8; MAX_LINE_LEN],
pos: usize,
}
impl LineReader {
pub fn new() -> Self {
LineReader {
buf: [0; MAX_LINE_LEN],
pos: 0,
}
}
pub fn feed(&mut self, c: u8) -> Option<&[u8]> {
2020-03-14 06:39:22 +08:00
if c == 13 || c == 10 {
// Enter
if self.pos > 0 {
let len = self.pos;
self.pos = 0;
Some(&self.buf[..len])
2020-03-14 06:39:22 +08:00
} else {
None
}
} else if self.pos < self.buf.len() {
// Add input
self.buf[self.pos] = c;
self.pos += 1;
None
} else {
// Buffer is full, ignore
None
}
}
}
pub enum SessionInput {
2020-03-14 06:39:22 +08:00
Nothing,
Command(Command),
Error(ParserError),
}
impl From<Result<Command, ParserError>> for SessionInput {
2020-03-14 06:39:22 +08:00
fn from(input: Result<Command, ParserError>) -> Self {
2024-10-14 11:52:15 +08:00
input
.map(SessionInput::Command)
.unwrap_or_else(SessionInput::Error)
2020-03-14 06:39:22 +08:00
}
}
pub struct Session {
reader: LineReader,
}
impl Default for Session {
fn default() -> Self {
Session::new()
}
}
impl Session {
pub fn new() -> Self {
Session {
reader: LineReader::new(),
}
}
pub fn reset(&mut self) {
self.reader = LineReader::new();
}
pub fn feed(&mut self, buf: &[u8]) -> (usize, SessionInput) {
2020-03-14 06:39:22 +08:00
let mut buf_bytes = 0;
for (i, b) in buf.iter().enumerate() {
buf_bytes = i + 1;
let line = self.reader.feed(*b);
match line {
Some(line) => {
let command = Command::parse(&line);
return (buf_bytes, command.into());
}
None => {}
}
}
(buf_bytes, SessionInput::Nothing)
2020-03-14 06:39:22 +08:00
}
}