use std::fmt;
use std::str::FromStr;
use thiserror::Error;
#[derive(Clone, Debug, Eq, Error, Hash, PartialEq)]
pub struct ParseKeywordError;
impl fmt::Display for ParseKeywordError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str("not a keyword")
}
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum Keyword {
Bang,
OpenBracketBracket,
Case,
Do,
Done,
Elif,
Else,
Esac,
Fi,
For,
Function,
If,
In,
Then,
Until,
While,
OpenBrace,
CloseBrace,
}
impl Keyword {
#[must_use]
pub const fn as_str(&self) -> &'static str {
use Keyword::*;
match self {
Bang => "!",
OpenBracketBracket => "[[",
Case => "case",
Do => "do",
Done => "done",
Elif => "elif",
Else => "else",
Esac => "esac",
Fi => "fi",
For => "for",
Function => "function",
If => "if",
In => "in",
Then => "then",
Until => "until",
While => "while",
OpenBrace => "{",
CloseBrace => "}",
}
}
#[must_use]
pub const fn is_clause_delimiter(self) -> bool {
use Keyword::*;
match self {
Do | Done | Elif | Else | Esac | Fi | Then | CloseBrace => true,
Bang | OpenBracketBracket | Case | For | Function | If | In | Until | While
| OpenBrace => false,
}
}
}
impl fmt::Display for Keyword {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(self.as_str())
}
}
impl FromStr for Keyword {
type Err = ParseKeywordError;
fn from_str(s: &str) -> Result<Keyword, ParseKeywordError> {
use Keyword::*;
match s {
"!" => Ok(Bang),
"[[" => Ok(OpenBracketBracket),
"case" => Ok(Case),
"do" => Ok(Do),
"done" => Ok(Done),
"elif" => Ok(Elif),
"else" => Ok(Else),
"esac" => Ok(Esac),
"fi" => Ok(Fi),
"for" => Ok(For),
"function" => Ok(Function),
"if" => Ok(If),
"in" => Ok(In),
"then" => Ok(Then),
"until" => Ok(Until),
"while" => Ok(While),
"{" => Ok(OpenBrace),
"}" => Ok(CloseBrace),
_ => Err(ParseKeywordError),
}
}
}