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