use std::fmt;
use crate::tokens::{
AtomToken, CharToken, FloatToken, IntegerToken, KeywordToken, StringToken, SymbolToken,
VariableToken,
};
use crate::{Position, PositionRange};
#[allow(missing_docs)]
#[derive(Debug, Clone)]
pub enum LexicalToken {
Atom(AtomToken),
Char(CharToken),
Float(FloatToken),
Integer(IntegerToken),
Keyword(KeywordToken),
String(StringToken),
Symbol(SymbolToken),
Variable(VariableToken),
}
impl LexicalToken {
pub fn text(&self) -> &str {
match *self {
LexicalToken::Atom(ref t) => t.text(),
LexicalToken::Char(ref t) => t.text(),
LexicalToken::Float(ref t) => t.text(),
LexicalToken::Integer(ref t) => t.text(),
LexicalToken::Keyword(ref t) => t.text(),
LexicalToken::String(ref t) => t.text(),
LexicalToken::Symbol(ref t) => t.text(),
LexicalToken::Variable(ref t) => t.text(),
}
}
pub fn as_atom_token(&self) -> Option<&AtomToken> {
if let LexicalToken::Atom(ref t) = *self {
Some(t)
} else {
None
}
}
pub fn as_char_token(&self) -> Option<&CharToken> {
if let LexicalToken::Char(ref t) = *self {
Some(t)
} else {
None
}
}
pub fn as_float_token(&self) -> Option<&FloatToken> {
if let LexicalToken::Float(ref t) = *self {
Some(t)
} else {
None
}
}
pub fn as_integer_token(&self) -> Option<&IntegerToken> {
if let LexicalToken::Integer(ref t) = *self {
Some(t)
} else {
None
}
}
pub fn as_keyword_token(&self) -> Option<&KeywordToken> {
if let LexicalToken::Keyword(ref t) = *self {
Some(t)
} else {
None
}
}
pub fn as_string_token(&self) -> Option<&StringToken> {
if let LexicalToken::String(ref t) = *self {
Some(t)
} else {
None
}
}
pub fn as_symbol_token(&self) -> Option<&SymbolToken> {
if let LexicalToken::Symbol(ref t) = *self {
Some(t)
} else {
None
}
}
pub fn as_variable_token(&self) -> Option<&VariableToken> {
if let LexicalToken::Variable(ref t) = *self {
Some(t)
} else {
None
}
}
pub fn into_atom_token(self) -> Result<AtomToken, Self> {
if let LexicalToken::Atom(t) = self {
Ok(t)
} else {
Err(self)
}
}
pub fn into_char_token(self) -> Result<CharToken, Self> {
if let LexicalToken::Char(t) = self {
Ok(t)
} else {
Err(self)
}
}
pub fn into_float_token(self) -> Result<FloatToken, Self> {
if let LexicalToken::Float(t) = self {
Ok(t)
} else {
Err(self)
}
}
pub fn into_integer_token(self) -> Result<IntegerToken, Self> {
if let LexicalToken::Integer(t) = self {
Ok(t)
} else {
Err(self)
}
}
pub fn into_keyword_token(self) -> Result<KeywordToken, Self> {
if let LexicalToken::Keyword(t) = self {
Ok(t)
} else {
Err(self)
}
}
pub fn into_string_token(self) -> Result<StringToken, Self> {
if let LexicalToken::String(t) = self {
Ok(t)
} else {
Err(self)
}
}
pub fn into_symbol_token(self) -> Result<SymbolToken, Self> {
if let LexicalToken::Symbol(t) = self {
Ok(t)
} else {
Err(self)
}
}
pub fn into_variable_token(self) -> Result<VariableToken, Self> {
if let LexicalToken::Variable(t) = self {
Ok(t)
} else {
Err(self)
}
}
}
impl From<AtomToken> for LexicalToken {
fn from(f: AtomToken) -> Self {
LexicalToken::Atom(f)
}
}
impl From<CharToken> for LexicalToken {
fn from(f: CharToken) -> Self {
LexicalToken::Char(f)
}
}
impl From<FloatToken> for LexicalToken {
fn from(f: FloatToken) -> Self {
LexicalToken::Float(f)
}
}
impl From<IntegerToken> for LexicalToken {
fn from(f: IntegerToken) -> Self {
LexicalToken::Integer(f)
}
}
impl From<KeywordToken> for LexicalToken {
fn from(f: KeywordToken) -> Self {
LexicalToken::Keyword(f)
}
}
impl From<StringToken> for LexicalToken {
fn from(f: StringToken) -> Self {
LexicalToken::String(f)
}
}
impl From<SymbolToken> for LexicalToken {
fn from(f: SymbolToken) -> Self {
LexicalToken::Symbol(f)
}
}
impl From<VariableToken> for LexicalToken {
fn from(f: VariableToken) -> Self {
LexicalToken::Variable(f)
}
}
impl PositionRange for LexicalToken {
fn start_position(&self) -> Position {
match *self {
LexicalToken::Atom(ref t) => t.start_position(),
LexicalToken::Char(ref t) => t.start_position(),
LexicalToken::Float(ref t) => t.start_position(),
LexicalToken::Integer(ref t) => t.start_position(),
LexicalToken::Keyword(ref t) => t.start_position(),
LexicalToken::String(ref t) => t.start_position(),
LexicalToken::Symbol(ref t) => t.start_position(),
LexicalToken::Variable(ref t) => t.start_position(),
}
}
fn end_position(&self) -> Position {
match *self {
LexicalToken::Atom(ref t) => t.end_position(),
LexicalToken::Char(ref t) => t.end_position(),
LexicalToken::Float(ref t) => t.end_position(),
LexicalToken::Integer(ref t) => t.end_position(),
LexicalToken::Keyword(ref t) => t.end_position(),
LexicalToken::String(ref t) => t.end_position(),
LexicalToken::Symbol(ref t) => t.end_position(),
LexicalToken::Variable(ref t) => t.end_position(),
}
}
}
impl fmt::Display for LexicalToken {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.text().fmt(f)
}
}