1mod r#impl;
4
5use smol_str::SmolStr;
6
7use crate::prelude::{ParseError, Position};
8
9crate_reexport!(literal, keyword, symbol, operator, comment);
10
11#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
14#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
15pub struct Token {
16 pub start: Position,
18
19 pub leading_trivia: Vec<Trivia>,
21
22 pub token_type: TokenType,
24
25 pub trailing_trivia: Vec<Trivia>,
27
28 pub end: Position,
30}
31
32#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
34#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
35pub enum Trivia {
36 Spaces(SmolStr),
38
39 Comment(Comment),
41}
42
43impl Token {
44 #[inline]
47 pub const fn empty(token_type: TokenType) -> Self {
48 Self {
49 start: Position::MAX,
50 leading_trivia: Vec::new(),
51 token_type,
52 trailing_trivia: Vec::new(),
53 end: Position::MAX,
54 }
55 }
56}
57
58impl PartialEq<TokenType> for Token {
59 fn eq(&self, other: &TokenType) -> bool {
60 &self.token_type == other
61 }
62}
63
64#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
66#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
67pub enum TokenType {
68 Error(ParseError),
70
71 Literal(Literal),
73
74 Identifier(SmolStr),
76
77 Comment(Comment),
79
80 Keyword(Keyword),
82
83 PartialKeyword(PartialKeyword),
85
86 Symbol(Symbol),
88
89 Operator(Operator),
91
92 CompoundOperator(CompoundOperator),
94
95 EndOfFile,
97}
98
99impl TokenType {
100 pub fn into_token(
102 self,
103 start: Position,
104 end: Position,
105 leading_trivia: Vec<Trivia>,
106 trailing_trivia: Vec<Trivia>,
107 ) -> Token {
108 Token {
109 start,
110 leading_trivia,
111 token_type: self,
112 trailing_trivia,
113 end,
114 }
115 }
116}
117
118impl TokenType {
119 pub fn try_as_string(&self) -> Option<String> {
121 match self {
122 TokenType::Literal(literal) => match literal {
123 Literal::Number(luau_number) => match luau_number {
124 LuauNumber::Plain(smol_str)
125 | LuauNumber::Binary(smol_str)
126 | LuauNumber::Hex(smol_str) => Some(smol_str.to_string()),
127 },
128 Literal::String(luau_string) => match luau_string {
129 LuauString::SingleQuotes(smol_str)
130 | LuauString::DoubleQuotes(smol_str)
131 | LuauString::Backticks(smol_str)
132 | LuauString::MultiLine(smol_str) => Some(smol_str.to_string()),
133 },
134 Literal::Boolean(true) => Some("true".to_string()),
135 Literal::Boolean(false) => Some("false".to_string()),
136 },
137 TokenType::Identifier(smol_str) => Some(smol_str.to_string()),
138 TokenType::Comment(comment) => match comment {
139 Comment::MultiLine(smol_str) | Comment::SingleLine(smol_str) => {
140 Some(smol_str.to_string())
141 }
142 },
143 TokenType::Keyword(keyword) => Some(keyword.to_string()),
144 TokenType::PartialKeyword(partial_keyword) => Some(partial_keyword.to_string()),
145 TokenType::Symbol(symbol) => Some(symbol.to_string()),
146 TokenType::Operator(operator) => Some(operator.to_string()),
147 TokenType::CompoundOperator(compound_operator) => Some(compound_operator.to_string()),
148 _ => None,
149 }
150 }
151}
152
153impl_from!(TokenType <= {
154 Error(ParseError),
155 Literal(Literal),
156 Keyword(Keyword),
157 PartialKeyword(PartialKeyword),
158 Symbol(Symbol),
159 Operator(Operator),
160 CompoundOperator(CompoundOperator),
161});