1use crate::{
7 Error, Ident, LiteralCharacter, LiteralInteger, Parse, Parser, RefineErr, Result, Span,
8 ToTokens, TokenIter, TokenStream, TokenTree,
9};
10
11macro_rules! impl_unsigned_integer {
13 ($($ty:ty),*) => {
14 $(
15 #[doc = stringify!(Parse $ty may have a positive sign but no suffix)]
16 impl Parser for $ty {
17 fn parser(tokens: &mut TokenIter) -> Result<Self> {
18 let at = tokens.clone().next();
19 let lit = crate::Cons::<Option<crate::Plus>, LiteralInteger>::parser(tokens).refine_err::<Self>()?;
20 <$ty>::try_from(lit.second.value())
21 .or_else(|e| Error::dynamic::<Self>(at, tokens, e))
22 }
23 }
24
25 #[doc = stringify!(Emit a literal $ty without sign and suffix)]
26 impl ToTokens for $ty {
27 fn to_tokens(&self, tokens: &mut TokenStream) {
28 #[allow(clippy::cast_lossless)]
29 LiteralInteger::new(*self as u128).to_tokens(tokens);
30 }
31 }
32
33 #[doc = stringify!(Emit a literal $ty without sign and suffix)]
34 impl ToTokens for &$ty {
35 fn to_tokens(&self, tokens: &mut TokenStream) {
36 #[allow(clippy::cast_lossless)]
37 LiteralInteger::new(**self as u128).to_tokens(tokens);
38 }
39 }
40 )*
41 };
42}
43
44impl_unsigned_integer! {u8, u16, u32, u64, u128, usize}
45
46macro_rules! impl_signed_integer {
48 ($($ty:ty),*) => {
49 $(
50 #[doc = stringify!(Parse $ty may have a positive or negative sign but no suffix)]
51 impl Parser for $ty {
52 fn parser(tokens: &mut TokenIter) -> Result<Self> {
53 let at = tokens.clone().next();
54 let lit = crate::Cons::<Option<crate::Either<crate::Plus, crate::Minus>>, LiteralInteger>::parser(tokens).refine_err::<Self>()?;
55 let value = <$ty>::try_from(lit.second.value())
56 .or_else(|e| Error::dynamic::<Self>(at, tokens, e))?;
57 match lit.first {
58 Some(crate::Either::Second(_)) => Ok(-value),
59 _ => Ok(value),
60 }
61 }
62 }
63
64 #[doc = stringify!(Emit a literal $ty with negative sign and without suffix)]
65 impl ToTokens for $ty {
66 fn to_tokens(&self, tokens: &mut TokenStream) {
67 if *self < 0 {
68 crate::Minus::new().to_tokens(tokens);
69 }
70 LiteralInteger::new(self.abs().try_into().unwrap()).to_tokens(tokens);
71 }
72 }
73
74 #[doc = stringify!(Emit a literal $ty with negative sign and without suffix)]
75 impl ToTokens for &$ty {
76 fn to_tokens(&self, tokens: &mut TokenStream) {
77 if **self < 0 {
78 crate::Minus::new().to_tokens(tokens);
79 }
80 LiteralInteger::new(self.abs().try_into().unwrap()).to_tokens(tokens);
81 }
82 }
83 )*
84 };
85}
86
87impl_signed_integer! {i8, i16, i32, i64, i128, isize}
88
89impl Parser for char {
91 fn parser(tokens: &mut TokenIter) -> Result<Self> {
92 let lit = LiteralCharacter::parser(tokens).refine_err::<Self>()?;
93 Ok(lit.value())
94 }
95}
96
97impl ToTokens for char {
98 fn to_tokens(&self, tokens: &mut TokenStream) {
99 LiteralCharacter::new(*self).to_tokens(tokens);
100 }
101}
102
103#[cfg(not(feature = "proc_macro2"))]
108#[mutants::skip]
109fn parse_bool_ident(ident: &Ident, at: Option<TokenTree>, tokens: &mut TokenIter) -> Result<bool> {
110 let ident_str = ident.to_string();
111 if ident_str == "true" {
112 Ok(true)
113 } else if ident_str == "false" {
114 Ok(false)
115 } else {
116 Error::unexpected_token(at, tokens)
117 }
118}
119
120impl Parser for bool {
124 fn parser(tokens: &mut TokenIter) -> Result<Self> {
125 let at = tokens.clone().next();
126 Ident::parse_with(tokens, |ident, tokens| {
127 #[cfg(feature = "proc_macro2")]
130 {
131 if ident == "true" {
132 Ok(true)
133 } else if ident == "false" {
134 Ok(false)
135 } else {
136 Error::unexpected_token(at, tokens)
137 }
138 }
139 #[cfg(not(feature = "proc_macro2"))]
140 {
141 parse_bool_ident(&ident, at, tokens)
142 }
143 })
144 .refine_err::<Self>()
145 }
146}
147
148impl ToTokens for bool {
149 fn to_tokens(&self, tokens: &mut TokenStream) {
150 Ident::new(if *self { "true" } else { "false" }, Span::call_site()).to_tokens(tokens);
151 }
152}
153
154impl Parser for String {
160 fn parser(tokens: &mut TokenIter) -> Result<Self> {
161 TokenTree::parse_with(tokens, |token, _| Ok(token.to_string())).refine_err::<Self>()
162 }
163}
164
165#[cfg(feature = "proc_macro2")]
179impl ToTokens for &str {
180 fn to_tokens(&self, tokens: &mut TokenStream) {
181 use std::str::FromStr;
182 let ts = TokenStream::from_str(self).expect("Failed to tokenize input string.");
183 tokens.extend(ts);
184 }
185}
186
187#[cfg(feature = "proc_macro2")]
188impl ToTokens for str {
189 fn to_tokens(&self, tokens: &mut TokenStream) {
190 use std::str::FromStr;
191 let ts = TokenStream::from_str(self).expect("Failed to tokenize input string.");
192 tokens.extend(ts);
193 }
194}
195
196#[cfg(feature = "proc_macro2")]
197impl ToTokens for &String {
198 fn to_tokens(&self, tokens: &mut TokenStream) {
199 self.as_str().to_tokens(tokens);
200 }
201}
202
203impl<T> Parser for std::marker::PhantomData<T> {
205 #[inline]
206 #[mutants::skip]
207 fn parser(_tokens: &mut TokenIter) -> Result<Self> {
208 Ok(Self)
209 }
210}
211
212impl<T> ToTokens for std::marker::PhantomData<T> {
213 #[inline]
214 fn to_tokens(&self, _tokens: &mut TokenStream) {
215 }
217}
218
219impl<A: Parse, B: Parse> Parser for (A, B) {
235 fn parser(tokens: &mut TokenIter) -> Result<Self> {
236 Ok((A::parser(tokens)?, B::parser(tokens)?))
237 }
238}
239
240impl<A: ToTokens, B: ToTokens> ToTokens for (A, B) {
251 fn to_tokens(&self, tokens: &mut TokenStream) {
252 self.0.to_tokens(tokens);
253 self.1.to_tokens(tokens);
254 }
255}
256
257impl<A: Parse, B: Parse, C: Parse> Parser for (A, B, C) {
270 fn parser(tokens: &mut TokenIter) -> Result<Self> {
271 Ok((A::parser(tokens)?, B::parser(tokens)?, C::parser(tokens)?))
272 }
273}
274
275impl<A: ToTokens, B: ToTokens, C: ToTokens> ToTokens for (A, B, C) {
277 fn to_tokens(&self, tokens: &mut TokenStream) {
278 self.0.to_tokens(tokens);
279 self.1.to_tokens(tokens);
280 self.2.to_tokens(tokens);
281 }
282}
283
284impl<A: Parse, B: Parse, C: Parse, D: Parse> Parser for (A, B, C, D) {
295 fn parser(tokens: &mut TokenIter) -> Result<Self> {
296 Ok((
297 A::parser(tokens)?,
298 B::parser(tokens)?,
299 C::parser(tokens)?,
300 D::parser(tokens)?,
301 ))
302 }
303}
304
305impl<A: ToTokens, B: ToTokens, C: ToTokens, D: ToTokens> ToTokens for (A, B, C, D) {
307 fn to_tokens(&self, tokens: &mut TokenStream) {
308 self.0.to_tokens(tokens);
309 self.1.to_tokens(tokens);
310 self.2.to_tokens(tokens);
311 self.3.to_tokens(tokens);
312 }
313}