2019-09-11 06:23:15 +08:00
|
|
|
use logos::Logos;
|
2019-09-11 05:37:51 +08:00
|
|
|
use super::session::ReportMode;
|
|
|
|
|
|
|
|
#[derive(Logos, Debug, PartialEq)]
|
|
|
|
enum Token {
|
|
|
|
#[end]
|
|
|
|
End,
|
|
|
|
#[error]
|
|
|
|
Error,
|
|
|
|
|
|
|
|
#[token = "Quit"]
|
|
|
|
Quit,
|
|
|
|
#[token = "show"]
|
|
|
|
Show,
|
|
|
|
#[token = "channel"]
|
|
|
|
Channel,
|
|
|
|
#[token = "report"]
|
|
|
|
Report,
|
|
|
|
#[token = "mode"]
|
|
|
|
Mode,
|
|
|
|
#[token = "off"]
|
|
|
|
Off,
|
|
|
|
#[token = "once"]
|
|
|
|
Once,
|
|
|
|
#[token = "continuous"]
|
|
|
|
Continuous,
|
2019-09-12 22:12:03 +08:00
|
|
|
#[token = "enable"]
|
|
|
|
Enable,
|
|
|
|
#[token = "disable"]
|
|
|
|
Disable,
|
2019-09-13 07:04:59 +08:00
|
|
|
#[token = "setup"]
|
|
|
|
Setup,
|
2019-09-11 05:37:51 +08:00
|
|
|
|
|
|
|
#[regex = "[0-9]+"]
|
|
|
|
Number,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug)]
|
|
|
|
pub enum Error {
|
|
|
|
Parser,
|
|
|
|
UnexpectedEnd,
|
|
|
|
UnexpectedToken(Token),
|
2019-09-12 22:12:03 +08:00
|
|
|
NoSuchChannel,
|
2019-09-13 07:04:59 +08:00
|
|
|
NoSuchSetup,
|
2019-09-11 05:37:51 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug)]
|
2019-09-11 06:23:15 +08:00
|
|
|
pub enum ShowCommand {
|
2019-09-11 05:37:51 +08:00
|
|
|
ReportMode,
|
|
|
|
}
|
|
|
|
|
2019-09-12 22:12:03 +08:00
|
|
|
|
|
|
|
#[derive(Debug)]
|
|
|
|
pub enum ChannelCommand {
|
|
|
|
Enable,
|
|
|
|
Disable,
|
2019-09-13 07:04:59 +08:00
|
|
|
Setup(u8),
|
2019-09-12 22:12:03 +08:00
|
|
|
}
|
|
|
|
|
2019-09-11 05:37:51 +08:00
|
|
|
#[derive(Debug)]
|
|
|
|
pub enum Command {
|
|
|
|
Quit,
|
2019-09-11 06:23:15 +08:00
|
|
|
Show(ShowCommand),
|
2019-09-11 05:37:51 +08:00
|
|
|
Report(ReportMode),
|
2019-09-12 22:12:03 +08:00
|
|
|
Channel(u8, ChannelCommand),
|
2019-09-11 05:37:51 +08:00
|
|
|
}
|
|
|
|
|
2019-09-12 22:12:03 +08:00
|
|
|
const CHANNEL_IDS: &'static [&'static str] = &[
|
|
|
|
"0", "1", "2", "3",
|
|
|
|
];
|
2019-09-13 07:04:59 +08:00
|
|
|
const SETUP_IDS: &'static [&'static str] = CHANNEL_IDS;
|
2019-09-11 05:37:51 +08:00
|
|
|
|
|
|
|
impl Command {
|
|
|
|
pub fn parse(input: &str) -> Result<Self, Error> {
|
|
|
|
let mut lexer = Token::lexer(input);
|
|
|
|
|
2019-09-13 07:04:59 +08:00
|
|
|
/// Match against a set of expected tokens
|
2019-09-11 05:37:51 +08:00
|
|
|
macro_rules! choice {
|
|
|
|
[$($token: tt => $block: stmt,)*] => {
|
|
|
|
match lexer.token {
|
|
|
|
$(
|
|
|
|
Token::$token => {
|
|
|
|
lexer.advance();
|
|
|
|
$block
|
|
|
|
}
|
|
|
|
)*
|
|
|
|
Token::End => Err(Error::UnexpectedEnd),
|
|
|
|
_ => Err(Error::UnexpectedToken(lexer.token))
|
|
|
|
}
|
2019-09-13 07:04:59 +08:00
|
|
|
};
|
|
|
|
}
|
|
|
|
/// Expecting no further tokens
|
|
|
|
macro_rules! end {
|
|
|
|
($result: expr) => {
|
|
|
|
match lexer.token {
|
|
|
|
Token::End => Ok($result),
|
|
|
|
_ => Err(Error::UnexpectedToken(lexer.token)),
|
|
|
|
}
|
|
|
|
};
|
2019-09-11 05:37:51 +08:00
|
|
|
}
|
|
|
|
|
2019-09-13 07:04:59 +08:00
|
|
|
// Command grammar
|
2019-09-11 05:37:51 +08:00
|
|
|
choice![
|
|
|
|
Quit => Ok(Command::Quit),
|
|
|
|
Report => choice![
|
|
|
|
Mode => choice![
|
2019-09-13 07:04:59 +08:00
|
|
|
End => end!(Command::Show(ShowCommand::ReportMode)),
|
2019-09-11 05:37:51 +08:00
|
|
|
Off => Ok(Command::Report(ReportMode::Off)),
|
|
|
|
Once => Ok(Command::Report(ReportMode::Once)),
|
|
|
|
Continuous => Ok(Command::Report(ReportMode::Continuous)),
|
|
|
|
],
|
|
|
|
End => Ok(Command::Report(ReportMode::Once)),
|
|
|
|
],
|
2019-09-12 22:12:03 +08:00
|
|
|
Channel => choice![
|
|
|
|
Number => {
|
|
|
|
let channel = CHANNEL_IDS.iter()
|
|
|
|
.position(|id| *id == lexer.slice());
|
|
|
|
match channel {
|
|
|
|
Some(channel) => {
|
|
|
|
choice![
|
|
|
|
Enable => Ok(Command::Channel(
|
|
|
|
channel as u8,
|
|
|
|
ChannelCommand::Enable
|
|
|
|
)),
|
|
|
|
Disable => Ok(Command::Channel(
|
|
|
|
channel as u8,
|
|
|
|
ChannelCommand::Enable
|
|
|
|
)),
|
2019-09-13 07:04:59 +08:00
|
|
|
Setup => choice![
|
|
|
|
Number => {
|
|
|
|
let setup = SETUP_IDS.iter()
|
|
|
|
.position(|id| *id == lexer.slice());
|
|
|
|
match setup {
|
|
|
|
Some(setup) =>
|
|
|
|
end!(Command::Channel(
|
|
|
|
channel as u8,
|
|
|
|
ChannelCommand::Setup(setup as u8)
|
|
|
|
)),
|
|
|
|
None =>
|
|
|
|
Err(Error::NoSuchSetup)
|
|
|
|
}
|
|
|
|
},
|
|
|
|
],
|
2019-09-12 22:12:03 +08:00
|
|
|
]
|
|
|
|
}
|
|
|
|
None => Err(Error::NoSuchChannel)
|
|
|
|
}
|
|
|
|
},
|
|
|
|
],
|
2019-09-11 05:37:51 +08:00
|
|
|
]
|
|
|
|
}
|
|
|
|
}
|