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,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-03-19 04:33:10 +08:00
|
|
|
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;
|
2020-03-19 04:33:10 +08:00
|
|
|
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
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-10-01 05:35:11 +08:00
|
|
|
pub enum SessionInput {
|
2020-03-14 06:39:22 +08:00
|
|
|
Nothing,
|
|
|
|
Command(Command),
|
|
|
|
Error(ParserError),
|
|
|
|
}
|
|
|
|
|
2020-10-01 05:35:11 +08:00
|
|
|
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)
|
2020-10-01 05:35:11 +08:00
|
|
|
.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();
|
|
|
|
}
|
|
|
|
|
2020-10-01 05:35:11 +08:00
|
|
|
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 => {}
|
|
|
|
}
|
|
|
|
}
|
2020-10-01 05:35:11 +08:00
|
|
|
(buf_bytes, SessionInput::Nothing)
|
2020-03-14 06:39:22 +08:00
|
|
|
}
|
|
|
|
}
|