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 pub const END_OF_FILE: Self = Self::empty(TokenType::EndOfFile);
46
47 #[inline]
50 pub const fn empty(token_type: TokenType) -> Self {
51 Self {
52 start: Position::MAX,
53 leading_trivia: Vec::new(),
54 token_type,
55 trailing_trivia: Vec::new(),
56 end: Position::MAX,
57 }
58 }
59}
60
61impl PartialEq<TokenType> for Token {
62 fn eq(&self, other: &TokenType) -> bool {
63 &self.token_type == other
64 }
65}
66
67#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
69#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
70pub enum TokenType {
71 Error(ParseError),
73
74 Literal(Literal),
76
77 Identifier(SmolStr),
79
80 Comment(Comment),
82
83 Keyword(Keyword),
85
86 PartialKeyword(PartialKeyword),
88
89 Symbol(Symbol),
91
92 Operator(Operator),
94
95 CompoundOperator(CompoundOperator),
97
98 EndOfFile,
100}
101
102impl TokenType {
103 pub fn into_token(
105 self,
106 start: Position,
107 end: Position,
108 leading_trivia: Vec<Trivia>,
109 trailing_trivia: Vec<Trivia>,
110 ) -> Token {
111 Token {
112 start,
113 leading_trivia,
114 token_type: self,
115 trailing_trivia,
116 end,
117 }
118 }
119}
120
121impl TokenType {
122 pub fn try_as_string(&self) -> Option<String> {
124 match self {
125 TokenType::Literal(literal) => match literal {
126 Literal::Number(luau_number) => match luau_number {
127 LuauNumber::Plain(smol_str)
128 | LuauNumber::Binary(smol_str)
129 | LuauNumber::Hex(smol_str) => Some(smol_str.to_string()),
130 },
131 Literal::String(luau_string) => match luau_string {
132 LuauString::SingleQuotes(smol_str)
133 | LuauString::DoubleQuotes(smol_str)
134 | LuauString::Backticks(smol_str)
135 | LuauString::MultiLine(smol_str) => Some(smol_str.to_string()),
136 },
137 Literal::Boolean(true) => Some("true".to_string()),
138 Literal::Boolean(false) => Some("false".to_string()),
139 },
140 TokenType::Identifier(smol_str) => Some(smol_str.to_string()),
141 TokenType::Comment(comment) => match comment {
142 Comment::MultiLine(smol_str) | Comment::SingleLine(smol_str) => {
143 Some(smol_str.to_string())
144 }
145 },
146 TokenType::Keyword(keyword) => Some(keyword.to_string()),
147 TokenType::PartialKeyword(partial_keyword) => Some(partial_keyword.to_string()),
148 TokenType::Symbol(symbol) => Some(symbol.to_string()),
149 TokenType::Operator(operator) => Some(operator.to_string()),
150 TokenType::CompoundOperator(compound_operator) => Some(compound_operator.to_string()),
151 _ => None,
152 }
153 }
154}
155
156impl_from!(TokenType <= {
157 Error(ParseError),
158 Literal(Literal),
159 Keyword(Keyword),
160 PartialKeyword(PartialKeyword),
161 Symbol(Symbol),
162 Operator(Operator),
163 CompoundOperator(CompoundOperator),
164});