1use crate::lex::{Cursor, LexError, Scan};
2use crate::parser::{ParseError, ParseStream};
3use crate::{Parse, Span, Spanner, ToTokens, TokenStream, TokenTree};
4
5pub mod float;
6pub mod int;
7
8mod r#bool;
9mod byte;
10mod byte_str;
11mod c_str;
12mod char;
13mod str;
14mod verbatim;
15
16pub use r#bool::*;
17pub use byte::*;
18pub use byte_str::*;
19pub use c_str::*;
20pub use char::*;
21pub use float::*;
22pub use int::*;
23pub use str::*;
24pub use verbatim::*;
25
26#[derive(Debug, Clone, PartialEq, Eq, Hash)]
27#[cfg_attr(feature = "serde", derive(serde::Serialize), serde(into = "String"))]
28pub enum Lit {
29 Int(LitInt),
30 Float(LitFloat),
31 Str(LitStr),
32 ByteStr(LitByteStr),
33 CStr(LitCStr),
34 Char(LitChar),
35 Byte(LitByte),
36 Bool(LitBool),
37 Verbatim(LitVerbatim),
38}
39
40impl Lit {
41 #[inline]
42 pub fn string(value: &str) -> Self {
43 Self::Str(LitStr::new(value, Span::default()))
44 }
45
46 #[inline]
47 pub fn char(value: char) -> Self {
48 Self::Char(LitChar::new(value, Span::default()))
49 }
50
51 #[inline]
55 pub fn from_repr(repr: &str, span: Span) -> Self {
56 use std::str::FromStr;
57
58 match TokenStream::from_str(repr).ok().and_then(|ts| ts.into_iter().next()) {
59 Some(TokenTree::Literal(mut lit)) if lit.repr() == repr => {
60 lit.set_span(span);
61 lit
62 }
63 _ => Self::Verbatim(LitVerbatim::new(repr, span)),
64 }
65 }
66
67 #[inline]
68 pub fn is_int(&self) -> bool {
69 matches!(self, Self::Int(_))
70 }
71
72 #[inline]
73 pub fn is_float(&self) -> bool {
74 matches!(self, Self::Float(_))
75 }
76
77 #[inline]
78 pub fn is_str(&self) -> bool {
79 matches!(self, Self::Str(_))
80 }
81
82 #[inline]
83 pub fn is_c_str(&self) -> bool {
84 matches!(self, Self::CStr(_))
85 }
86
87 #[inline]
88 pub fn is_bool(&self) -> bool {
89 matches!(self, Self::Bool(_))
90 }
91
92 #[inline]
93 pub fn is_char(&self) -> bool {
94 matches!(self, Self::Char(_))
95 }
96
97 #[inline]
98 pub fn is_byte(&self) -> bool {
99 matches!(self, Self::Byte(_))
100 }
101
102 #[inline]
103 pub fn is_byte_str(&self) -> bool {
104 matches!(self, Self::ByteStr(_))
105 }
106
107 #[inline]
108 pub fn is_verbatim(&self) -> bool {
109 matches!(self, Self::Verbatim(_))
110 }
111
112 #[inline]
113 pub fn as_str(&self) -> Option<&LitStr> {
114 if let Self::Str(v) = self { Some(v) } else { None }
115 }
116
117 #[inline]
118 pub fn as_c_str(&self) -> Option<&LitCStr> {
119 if let Self::CStr(v) = self { Some(v) } else { None }
120 }
121
122 #[inline]
123 pub fn as_bool(&self) -> Option<&LitBool> {
124 if let Self::Bool(v) = self { Some(v) } else { None }
125 }
126
127 #[inline]
128 pub fn as_int(&self) -> Option<&LitInt> {
129 if let Self::Int(v) = self { Some(v) } else { None }
130 }
131
132 #[inline]
133 pub fn as_float(&self) -> Option<&LitFloat> {
134 if let Self::Float(v) = self { Some(v) } else { None }
135 }
136
137 #[inline]
138 pub fn as_char(&self) -> Option<&LitChar> {
139 if let Self::Char(v) = self { Some(v) } else { None }
140 }
141
142 #[inline]
143 pub fn as_byte(&self) -> Option<&LitByte> {
144 if let Self::Byte(v) = self { Some(v) } else { None }
145 }
146
147 #[inline]
148 pub fn as_byte_str(&self) -> Option<&LitByteStr> {
149 if let Self::ByteStr(v) = self { Some(v) } else { None }
150 }
151
152 #[inline]
153 pub fn to_token_tree(&self) -> TokenTree {
154 TokenTree::Literal(self.clone())
155 }
156
157 #[inline]
158 pub fn into_token_tree(self) -> TokenTree {
159 TokenTree::Literal(self)
160 }
161
162 #[inline]
163 pub fn repr(&self) -> &str {
164 match self {
165 Self::Int(v) => v.repr(),
166 Self::Float(v) => v.repr(),
167 Self::Str(v) => v.repr(),
168 Self::ByteStr(v) => v.repr(),
169 Self::CStr(v) => v.repr(),
170 Self::Char(v) => v.repr(),
171 Self::Byte(v) => v.repr(),
172 Self::Bool(v) => v.repr(),
173 Self::Verbatim(v) => v.repr(),
174 }
175 }
176
177 #[inline]
178 pub fn span(&self) -> Span {
179 match self {
180 Self::Int(v) => v.span(),
181 Self::Float(v) => v.span(),
182 Self::Str(v) => v.span(),
183 Self::ByteStr(v) => v.span(),
184 Self::CStr(v) => v.span(),
185 Self::Char(v) => v.span(),
186 Self::Byte(v) => v.span(),
187 Self::Bool(v) => v.span(),
188 Self::Verbatim(v) => v.span(),
189 }
190 }
191
192 #[inline]
193 pub fn set_span(&mut self, span: Span) {
194 match self {
195 Self::Int(v) => v.set_span(span),
196 Self::Float(v) => v.set_span(span),
197 Self::Str(v) => v.set_span(span),
198 Self::ByteStr(v) => v.set_span(span),
199 Self::CStr(v) => v.set_span(span),
200 Self::Char(v) => v.set_span(span),
201 Self::Byte(v) => v.set_span(span),
202 Self::Bool(v) => v.set_span(span),
203 Self::Verbatim(v) => v.set_span(span),
204 }
205 }
206}
207
208impl Spanner for Lit {
209 fn span(&self) -> Span {
210 self.span()
211 }
212}
213
214impl std::fmt::Display for Lit {
215 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
216 f.write_str(self.repr())
217 }
218}
219
220#[cfg(feature = "serde")]
221impl From<Lit> for String {
222 fn from(value: Lit) -> Self {
223 value.repr().to_string()
224 }
225}
226
227impl Scan for Lit {
228 fn scan(cursor: Cursor<'_>) -> Result<(Cursor<'_>, Self), LexError> {
229 if let Ok((end, v)) = LitByte::scan(cursor) {
231 return Ok((end, Self::Byte(v)));
232 }
233
234 if let Ok((end, v)) = LitByteStr::scan(cursor) {
235 return Ok((end, Self::ByteStr(v)));
236 }
237
238 if let Ok((end, v)) = LitCStr::scan(cursor) {
239 return Ok((end, Self::CStr(v)));
240 }
241
242 if let Ok((end, v)) = LitStr::scan(cursor) {
243 return Ok((end, Self::Str(v)));
244 }
245
246 if let Ok((end, v)) = LitChar::scan(cursor) {
247 return Ok((end, Self::Char(v)));
248 }
249
250 if let Ok((end, v)) = LitFloat::scan(cursor) {
251 return Ok((end, Self::Float(v)));
252 }
253
254 if let Ok((end, v)) = LitInt::scan(cursor) {
255 return Ok((end, Self::Int(v)));
256 }
257
258 cursor.error().into()
259 }
260}
261
262impl ToTokens for Lit {
263 fn to_tokens(&self, tokens: &mut TokenStream) {
264 tokens.extend_one(TokenTree::Literal(self.clone()));
265 }
266}
267
268impl Parse for Lit {
269 fn parse(stream: &mut ParseStream) -> Result<Self, ParseError> {
270 match stream.advance() {
271 Some(TokenTree::Literal(v)) => Ok(v.clone()),
272 _ => Err(LexError::new(stream.span()).message("expected Literal").into()),
273 }
274 }
275}