use self::Token::*;
#[derive(Debug, Clone, PartialEq, PartialOrd)]
pub enum Token {
SELECT,
FROM,
WHERE,
ORDER,
INSERT,
INTO,
CREATE,
TABLE,
DROP,
IF,
EXISTS,
NOT,
NULL,
DEFAULT,
SERIAL,
AND,
OR,
INTEGER,
TEXT,
FLOAT,
BLOB,
EQUAL,
NOTEQUAL,
LESSTHAN,
LESSTHANOREQUAL,
GREATERTHAN,
GREATERTHANOREQUAL,
PLUS,
MINUS,
FORWARDSLASH,
LEFTPAREN,
RIGHTPAREN,
LEFTBRACKET,
RIGHTBRACKET,
DOT,
COMMA,
SEMICOLON,
ASTERISK,
AMPERSAND,
PIPE,
DOUBLEPIPE,
StringLiteral(String),
NumberLiteral(String),
Identifier(String),
}
impl Token {
pub fn from_char(c: char) -> Option<Token> {
Some(match c {
'=' => EQUAL,
'<' => LESSTHAN,
'>' => GREATERTHAN,
'+' => PLUS,
'-' => MINUS,
'(' => LEFTPAREN,
'[' => LEFTBRACKET,
')' => RIGHTPAREN,
']' => RIGHTBRACKET,
'.' => DOT,
',' => COMMA,
';' => SEMICOLON,
'*' => ASTERISK,
'&' => AMPERSAND,
'|' => PIPE,
'/' => FORWARDSLASH,
_ => return None,
})
}
pub fn from_str(s: &str) -> Token {
let word: String = s.chars().flat_map(|c| c.to_lowercase()).collect();
match word.as_ref() {
"select" => SELECT,
"from" => FROM,
"where" => WHERE,
"order" => ORDER,
"insert" => INSERT,
"into" => INTO,
"create" => CREATE,
"table" => TABLE,
"drop" => DROP,
"if" => IF,
"exists" => EXISTS,
"not" => NOT,
"null" => NULL,
"default" => DEFAULT,
"serial" => SERIAL,
"and" => AND,
"or" => OR,
"int" | "integer" => INTEGER,
"text" => TEXT,
"float" => FLOAT,
"blob" => BLOB,
_ => Identifier(word),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn from_char() {
assert_eq!(Token::from_char('.'), Some(Token::DOT));
assert_eq!(Token::from_char('#'), None);
}
#[test]
fn from_str() {
assert_eq!(Token::from_str("SEleCT"), Token::SELECT);
assert_eq!(Token::from_str("DROP"), Token::DROP);
assert_eq!(
Token::from_str("User_id"),
Token::Identifier("user_id".into())
);
}
}