1#![allow(clippy::module_name_repetitions)]
12
13#[cfg(doc)]
14use crate::*;
15
16use crate::{
17 Error, Literal, Parse, Parser, RefineErr, Result, ToTokens, TokenIter, TokenStream, TokenTree,
18};
19
20#[derive(Debug, Clone)]
24pub struct LiteralInteger {
25 literal: Literal,
27 value: u128,
29}
30
31impl LiteralInteger {
32 #[must_use]
34 pub fn new(value: u128) -> Self {
35 let literal = Literal::u128_unsuffixed(value);
36 Self { literal, value }
37 }
38
39 #[must_use]
41 pub const fn value(&self) -> u128 {
42 self.value
43 }
44
45 pub fn set(&mut self, value: u128) {
47 *self = Self {
48 literal: Literal::u128_unsuffixed(value),
49 value,
50 };
51 }
52
53 #[must_use]
55 pub fn into_inner(self) -> Literal {
56 self.literal
57 }
58}
59
60impl Parser for LiteralInteger {
61 fn parser(tokens: &mut TokenIter) -> Result<Self> {
62 let at = tokens.clone().next();
63 let literal = Literal::parser(tokens).refine_err::<Self>()?;
64 let value: u128 = match literal.to_string().parse() {
65 Ok(v) => v,
66 Err(e) => return Error::dynamic::<Self>(at, tokens, e),
67 };
68 Ok(Self { literal, value })
69 }
70}
71
72impl ToTokens for LiteralInteger {
73 fn to_tokens(&self, tokens: &mut TokenStream) {
74 self.literal.to_tokens(tokens);
75 }
76}
77
78impl PartialEq<u128> for LiteralInteger {
79 fn eq(&self, other: &u128) -> bool {
80 &self.value == other
81 }
82}
83
84impl From<LiteralInteger> for TokenTree {
85 fn from(lit: LiteralInteger) -> Self {
86 TokenTree::Literal(lit.into_inner())
87 }
88}
89
90#[test]
91fn test_literalinteger_into_tt() {
92 let lit = LiteralInteger::new(42);
93 let _: TokenTree = lit.into();
94}
95
96#[derive(Debug, Clone)]
107pub struct ConstInteger<const V: u128>(LiteralInteger);
108
109impl<const V: u128> ConstInteger<V> {
110 #[must_use]
112 pub const fn value(&self) -> u128 {
113 self.0.value
114 }
115
116 #[must_use]
118 pub fn into_inner(self) -> LiteralInteger {
119 self.0
120 }
121}
122
123impl<const V: u128> Parser for ConstInteger<V> {
124 fn parser(tokens: &mut TokenIter) -> Result<Self> {
125 let at = tokens.clone().next();
126 Parse::parse_with(tokens, |this: LiteralInteger, e| {
127 if this.value == V {
128 Ok(Self(this))
129 } else {
130 Error::unexpected_token(at, e)
131 }
132 })
133 .refine_err::<Self>()
134 }
135}
136
137impl<const V: u128> ToTokens for ConstInteger<V> {
138 fn to_tokens(&self, tokens: &mut TokenStream) {
139 self.0.to_tokens(tokens);
140 }
141}
142
143impl<const V: u128> Default for ConstInteger<V> {
144 fn default() -> Self {
145 Self(LiteralInteger::new(V))
146 }
147}
148
149#[derive(Debug, Clone)]
151pub struct LiteralCharacter {
152 literal: Literal,
154 value: char,
156}
157
158impl LiteralCharacter {
159 #[must_use]
161 pub fn new(value: char) -> Self {
162 let literal = Literal::character(value);
163 Self { literal, value }
164 }
165
166 #[must_use]
168 pub const fn value(&self) -> char {
169 self.value
170 }
171
172 pub fn set(&mut self, value: char) {
174 *self = Self {
175 literal: Literal::character(value),
176 value,
177 };
178 }
179
180 #[must_use]
182 pub fn into_inner(self) -> Literal {
183 self.literal
184 }
185}
186
187impl Parser for LiteralCharacter {
188 fn parser(tokens: &mut TokenIter) -> Result<Self> {
189 let at = tokens.clone().next();
190 let literal = Literal::parser(tokens).refine_err::<Self>()?;
191 let string = literal.to_string();
192 let mut chars = string.chars();
193 if let (Some('\''), Some(value)) = (chars.next(), chars.next()) {
196 Ok(Self { literal, value })
197 } else {
198 Error::unexpected_token(at, tokens)
199 }
200 }
201}
202
203impl ToTokens for LiteralCharacter {
204 fn to_tokens(&self, tokens: &mut TokenStream) {
205 self.literal.to_tokens(tokens);
206 }
207}
208
209impl PartialEq<char> for LiteralCharacter {
210 fn eq(&self, other: &char) -> bool {
211 &self.value == other
212 }
213}
214
215impl From<LiteralCharacter> for TokenTree {
216 fn from(lit: LiteralCharacter) -> Self {
217 TokenTree::Literal(lit.into_inner())
218 }
219}
220
221#[test]
222fn test_literalcharacter_into_tt() {
223 let lit = LiteralCharacter::new('c');
224 let _: TokenTree = lit.into();
225}
226
227#[derive(Debug, Clone)]
238pub struct ConstCharacter<const V: char>(LiteralCharacter);
239
240impl<const V: char> ConstCharacter<V> {
241 #[must_use]
243 pub const fn value(&self) -> char {
244 self.0.value
245 }
246
247 #[must_use]
249 pub fn into_inner(self) -> LiteralCharacter {
250 self.0
251 }
252}
253
254impl<const V: char> Parser for ConstCharacter<V> {
255 fn parser(tokens: &mut TokenIter) -> Result<Self> {
256 let at = tokens.clone().next();
257 Parse::parse_with(tokens, |this: LiteralCharacter, e| {
258 if this.value == V {
259 Ok(Self(this))
260 } else {
261 Error::unexpected_token(at, e)
262 }
263 })
264 .refine_err::<Self>()
265 }
266}
267
268impl<const V: char> ToTokens for ConstCharacter<V> {
269 fn to_tokens(&self, tokens: &mut TokenStream) {
270 self.0.to_tokens(tokens);
271 }
272}
273
274impl<const V: char> Default for ConstCharacter<V> {
275 fn default() -> Self {
276 Self(LiteralCharacter::new(V))
277 }
278}
279
280#[derive(Debug, Clone)]
284pub struct LiteralString {
285 literal: Literal,
287 value: String,
289}
290
291impl LiteralString {
292 #[must_use]
299 pub fn new(value: String) -> Self {
300 assert!(value.starts_with('"') && value.ends_with('"'));
301 let literal = Literal::string(&value);
302 Self { literal, value }
303 }
304
305 #[must_use]
308 #[allow(clippy::should_implement_trait)]
309 pub fn from_str(string: impl AsRef<str>) -> Self {
310 let string = string.as_ref();
311 let value = format!(r#""{string}""#);
312 let literal = Literal::string(string);
313 Self { literal, value }
314 }
315
316 #[must_use]
318 #[allow(clippy::missing_const_for_fn)] pub fn value(&self) -> &str {
320 &self.value
321 }
322
323 #[must_use]
325 pub fn as_str(&self) -> &str {
326 &self.value[1..self.value.len() - 1]
327 }
328
329 pub fn set(&mut self, value: String) {
331 *self = Self {
332 literal: Literal::string(&value),
333 value,
334 };
335 }
336
337 #[must_use]
339 pub fn into_inner(self) -> Literal {
340 self.literal
341 }
342}
343
344impl Parser for LiteralString {
345 fn parser(tokens: &mut TokenIter) -> Result<Self> {
346 let at = tokens.clone().next();
347 let literal = Literal::parser(tokens).refine_err::<Self>()?;
348 let string = literal.to_string();
349 if &string[0..1] == "\"" {
351 Ok(Self {
352 literal,
353 value: string,
354 })
355 } else {
356 Error::unexpected_token(at, tokens)
357 }
358 }
359}
360
361impl ToTokens for LiteralString {
362 fn to_tokens(&self, tokens: &mut TokenStream) {
363 self.literal.to_tokens(tokens);
364 }
365}
366
367impl PartialEq<&str> for LiteralString {
369 fn eq(&self, other: &&str) -> bool {
370 self.as_str() == *other
371 }
372}
373
374impl From<LiteralString> for TokenTree {
375 fn from(lit: LiteralString) -> Self {
376 TokenTree::Literal(lit.into_inner())
377 }
378}
379
380#[test]
381fn test_literalstring_into_tt() {
382 let lit = LiteralString::from_str("foobar");
383 let _: TokenTree = lit.into();
384}