command_parser: channel setup

master
Astro 2019-09-13 01:04:59 +02:00
parent edb0401838
commit 3fd1b2265d
1 changed files with 33 additions and 2 deletions

View File

@ -28,6 +28,8 @@ enum Token {
Enable, Enable,
#[token = "disable"] #[token = "disable"]
Disable, Disable,
#[token = "setup"]
Setup,
#[regex = "[0-9]+"] #[regex = "[0-9]+"]
Number, Number,
@ -39,6 +41,7 @@ pub enum Error {
UnexpectedEnd, UnexpectedEnd,
UnexpectedToken(Token), UnexpectedToken(Token),
NoSuchChannel, NoSuchChannel,
NoSuchSetup,
} }
#[derive(Debug)] #[derive(Debug)]
@ -51,6 +54,7 @@ pub enum ShowCommand {
pub enum ChannelCommand { pub enum ChannelCommand {
Enable, Enable,
Disable, Disable,
Setup(u8),
} }
#[derive(Debug)] #[derive(Debug)]
@ -64,11 +68,13 @@ pub enum Command {
const CHANNEL_IDS: &'static [&'static str] = &[ const CHANNEL_IDS: &'static [&'static str] = &[
"0", "1", "2", "3", "0", "1", "2", "3",
]; ];
const SETUP_IDS: &'static [&'static str] = CHANNEL_IDS;
impl Command { impl Command {
pub fn parse(input: &str) -> Result<Self, Error> { pub fn parse(input: &str) -> Result<Self, Error> {
let mut lexer = Token::lexer(input); let mut lexer = Token::lexer(input);
/// Match against a set of expected tokens
macro_rules! choice { macro_rules! choice {
[$($token: tt => $block: stmt,)*] => { [$($token: tt => $block: stmt,)*] => {
match lexer.token { match lexer.token {
@ -81,14 +87,24 @@ impl Command {
Token::End => Err(Error::UnexpectedEnd), Token::End => Err(Error::UnexpectedEnd),
_ => Err(Error::UnexpectedToken(lexer.token)) _ => Err(Error::UnexpectedToken(lexer.token))
} }
} };
}
/// Expecting no further tokens
macro_rules! end {
($result: expr) => {
match lexer.token {
Token::End => Ok($result),
_ => Err(Error::UnexpectedToken(lexer.token)),
}
};
} }
// Command grammar
choice![ choice![
Quit => Ok(Command::Quit), Quit => Ok(Command::Quit),
Report => choice![ Report => choice![
Mode => choice![ Mode => choice![
End => Ok(Command::Show(ShowCommand::ReportMode)), End => end!(Command::Show(ShowCommand::ReportMode)),
Off => Ok(Command::Report(ReportMode::Off)), Off => Ok(Command::Report(ReportMode::Off)),
Once => Ok(Command::Report(ReportMode::Once)), Once => Ok(Command::Report(ReportMode::Once)),
Continuous => Ok(Command::Report(ReportMode::Continuous)), Continuous => Ok(Command::Report(ReportMode::Continuous)),
@ -110,6 +126,21 @@ impl Command {
channel as u8, channel as u8,
ChannelCommand::Enable ChannelCommand::Enable
)), )),
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)
}
},
],
] ]
} }
None => Err(Error::NoSuchChannel) None => Err(Error::NoSuchChannel)