1#[cfg(feature = "parsing")]
92pub(crate) use self::private::CustomToken;
93use self::private::WithSpan;
94#[cfg(feature = "parsing")]
95use crate::buffer::Cursor;
96#[cfg(feature = "parsing")]
97use crate::error::Result;
98#[cfg(feature = "parsing")]
99use crate::lifetime::Lifetime;
100#[cfg(feature = "parsing")]
101use crate::parse::{Parse, ParseStream};
102use crate::span::IntoSpans;
103#[cfg(feature = "extra-traits")]
104use core::cmp;
105#[cfg(feature = "extra-traits")]
106use core::fmt::{self, Debug};
107#[cfg(feature = "extra-traits")]
108use core::hash::{Hash, Hasher};
109use core::ops::{Deref, DerefMut};
110use proc_macro2::extra::DelimSpan;
111use proc_macro2::Span;
112#[cfg(feature = "printing")]
113use proc_macro2::TokenStream;
114#[cfg(any(feature = "parsing", feature = "printing"))]
115use proc_macro2::{Delimiter, Ident};
116#[cfg(feature = "parsing")]
117use proc_macro2::{Literal, Punct, TokenTree};
118#[cfg(feature = "printing")]
119use quote::{ToTokens, TokenStreamExt as _};
120
121#[cfg(feature = "parsing")]
125pub trait Token: private::Sealed {
126 #[doc(hidden)]
128 fn peek(cursor: Cursor) -> bool;
129
130 #[doc(hidden)]
132 fn display() -> &'static str;
133}
134
135pub(crate) mod private {
136 #[cfg(feature = "parsing")]
137 use crate::buffer::Cursor;
138 use proc_macro2::Span;
139
140 #[cfg(feature = "parsing")]
141 pub trait Sealed {}
142
143 #[repr(transparent)]
146 #[allow(
147 unknown_lints,
148 renamed_and_removed_lints,
149 repr_transparent_non_zst_fields,
151 )]
152 pub struct WithSpan {
153 pub span: Span,
154 }
155
156 #[doc(hidden)]
158 #[cfg(feature = "parsing")]
159 pub trait CustomToken {
160 fn peek(cursor: Cursor) -> bool;
161 fn display() -> &'static str;
162 }
163}
164
165#[cfg(feature = "parsing")]
166impl private::Sealed for Ident {}
167
168macro_rules! impl_low_level_token {
169 ($display:literal $($path:ident)::+ $get:ident) => {
170 #[cfg(feature = "parsing")]
171 impl Token for $($path)::+ {
172 fn peek(cursor: Cursor) -> bool {
173 cursor.$get().is_some()
174 }
175
176 fn display() -> &'static str {
177 $display
178 }
179 }
180
181 #[cfg(feature = "parsing")]
182 impl private::Sealed for $($path)::+ {}
183 };
184}
185
186impl Token for Punct {
fn peek(cursor: Cursor) -> bool { cursor.punct().is_some() }
fn display() -> &'static str { "punctuation token" }
}
impl private::Sealed for Punct { }impl_low_level_token!("punctuation token" Punct punct);
187impl Token for Literal {
fn peek(cursor: Cursor) -> bool { cursor.literal().is_some() }
fn display() -> &'static str { "literal" }
}
impl private::Sealed for Literal { }impl_low_level_token!("literal" Literal literal);
188impl Token for TokenTree {
fn peek(cursor: Cursor) -> bool { cursor.token_tree().is_some() }
fn display() -> &'static str { "token" }
}
impl private::Sealed for TokenTree { }impl_low_level_token!("token" TokenTree token_tree);
189impl Token for proc_macro2::Group {
fn peek(cursor: Cursor) -> bool { cursor.any_group().is_some() }
fn display() -> &'static str { "group token" }
}
impl private::Sealed for proc_macro2::Group { }impl_low_level_token!("group token" proc_macro2::Group any_group);
190impl Token for Lifetime {
fn peek(cursor: Cursor) -> bool { cursor.lifetime().is_some() }
fn display() -> &'static str { "lifetime" }
}
impl private::Sealed for Lifetime { }impl_low_level_token!("lifetime" Lifetime lifetime);
191
192#[cfg(feature = "parsing")]
193impl<T: CustomToken> private::Sealed for T {}
194
195#[cfg(feature = "parsing")]
196impl<T: CustomToken> Token for T {
197 fn peek(cursor: Cursor) -> bool {
198 <Self as CustomToken>::peek(cursor)
199 }
200
201 fn display() -> &'static str {
202 <Self as CustomToken>::display()
203 }
204}
205
206macro_rules! define_keywords {
207 ($($token:literal pub struct $name:ident)*) => {
208 $(
209 #[doc = concat!('`', $token, '`')]
210 pub struct $name {
216 pub span: Span,
217 }
218
219 #[doc(hidden)]
220 #[allow(non_snake_case)]
221 pub fn $name<S: IntoSpans<Span>>(span: S) -> $name {
222 $name {
223 span: span.into_spans(),
224 }
225 }
226
227 impl core::default::Default for $name {
228 fn default() -> Self {
229 $name {
230 span: Span::call_site(),
231 }
232 }
233 }
234
235 #[cfg(feature = "clone-impls")]
236 #[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
237 impl Copy for $name {}
238
239 #[cfg(feature = "clone-impls")]
240 #[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
241 impl Clone for $name {
242 fn clone(&self) -> Self {
243 *self
244 }
245 }
246
247 #[cfg(feature = "extra-traits")]
248 #[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
249 impl Debug for $name {
250 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
251 format_token(f, $token)
252 }
253 }
254
255 #[cfg(feature = "extra-traits")]
256 #[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
257 impl cmp::Eq for $name {}
258
259 #[cfg(feature = "extra-traits")]
260 #[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
261 impl PartialEq for $name {
262 fn eq(&self, _other: &$name) -> bool {
263 true
264 }
265 }
266
267 #[cfg(feature = "extra-traits")]
268 #[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
269 impl Hash for $name {
270 fn hash<H: Hasher>(&self, _state: &mut H) {}
271 }
272
273 #[cfg(feature = "printing")]
274 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
275 impl ToTokens for $name {
276 fn to_tokens(&self, tokens: &mut TokenStream) {
277 printing::keyword($token, self.span, tokens);
278 }
279 }
280
281 #[cfg(feature = "parsing")]
282 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
283 impl Parse for $name {
284 fn parse(input: ParseStream) -> Result<Self> {
285 Ok($name {
286 span: parsing::keyword(input, $token)?,
287 })
288 }
289 }
290
291 #[cfg(feature = "parsing")]
292 impl Token for $name {
293 fn peek(cursor: Cursor) -> bool {
294 cursor.peek_keyword($token)
295 }
296
297 fn display() -> &'static str {
298 concat!("`", $token, "`")
299 }
300 }
301
302 #[cfg(feature = "parsing")]
303 impl private::Sealed for $name {}
304 )*
305 };
306}
307
308macro_rules! impl_deref_if_len_is_1 {
309 ($name:ident/1) => {
310 impl Deref for $name {
311 type Target = WithSpan;
312
313 fn deref(&self) -> &Self::Target {
314 unsafe { &*(self as *const Self).cast::<WithSpan>() }
315 }
316 }
317
318 impl DerefMut for $name {
319 fn deref_mut(&mut self) -> &mut Self::Target {
320 unsafe { &mut *(self as *mut Self).cast::<WithSpan>() }
321 }
322 }
323 };
324
325 ($name:ident/$len:literal) => {};
326}
327
328macro_rules! define_punctuation_structs {
329 ($($token:literal pub struct $name:ident/$len:tt #[doc = $usage:literal])*) => {
330 $(
331 #[cfg_attr(not(doc), repr(transparent))]
332 #[allow(
333 unknown_lints,
334 renamed_and_removed_lints,
335 repr_transparent_non_zst_fields,
337 )]
338 #[doc = concat!('`', $token, '`')]
339 #[doc = concat!($usage, '.')]
342 pub struct $name {
348 pub spans: [Span; $len],
349 }
350
351 #[doc(hidden)]
352 #[allow(non_snake_case)]
353 pub fn $name<S: IntoSpans<[Span; $len]>>(spans: S) -> $name {
354 $name {
355 spans: spans.into_spans(),
356 }
357 }
358
359 impl core::default::Default for $name {
360 fn default() -> Self {
361 $name {
362 spans: [Span::call_site(); $len],
363 }
364 }
365 }
366
367 #[cfg(feature = "clone-impls")]
368 #[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
369 impl Copy for $name {}
370
371 #[cfg(feature = "clone-impls")]
372 #[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
373 impl Clone for $name {
374 fn clone(&self) -> Self {
375 *self
376 }
377 }
378
379 #[cfg(feature = "extra-traits")]
380 #[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
381 impl Debug for $name {
382 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
383 format_token(f, $token)
384 }
385 }
386
387 #[cfg(feature = "extra-traits")]
388 #[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
389 impl cmp::Eq for $name {}
390
391 #[cfg(feature = "extra-traits")]
392 #[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
393 impl PartialEq for $name {
394 fn eq(&self, _other: &$name) -> bool {
395 true
396 }
397 }
398
399 #[cfg(feature = "extra-traits")]
400 #[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
401 impl Hash for $name {
402 fn hash<H: Hasher>(&self, _state: &mut H) {}
403 }
404
405 impl_deref_if_len_is_1!($name/$len);
406 )*
407 };
408}
409
410macro_rules! define_punctuation {
411 ($($token:literal pub struct $name:ident/$len:tt #[doc = $usage:literal])*) => {
412 $(
413 define_punctuation_structs! {
414 $token pub struct $name/$len #[doc = $usage]
415 }
416
417 #[cfg(feature = "printing")]
418 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
419 impl ToTokens for $name {
420 fn to_tokens(&self, tokens: &mut TokenStream) {
421 printing::punct($token, &self.spans, tokens);
422 }
423 }
424
425 #[cfg(feature = "parsing")]
426 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
427 impl Parse for $name {
428 fn parse(input: ParseStream) -> Result<Self> {
429 Ok($name {
430 spans: parsing::punct(input, $token)?,
431 })
432 }
433 }
434
435 #[cfg(feature = "parsing")]
436 impl Token for $name {
437 fn peek(cursor: Cursor) -> bool {
438 cursor.peek_punct($token)
439 }
440
441 fn display() -> &'static str {
442 concat!("`", $token, "`")
443 }
444 }
445
446 #[cfg(feature = "parsing")]
447 impl private::Sealed for $name {}
448 )*
449 };
450}
451
452macro_rules! define_delimiters {
453 ($($delim:ident pub struct $name:ident #[$doc:meta])*) => {
454 $(
455 #[$doc]
456 pub struct $name {
457 pub span: DelimSpan,
458 }
459
460 #[doc(hidden)]
461 #[allow(non_snake_case)]
462 pub fn $name<S: IntoSpans<DelimSpan>>(span: S) -> $name {
463 $name {
464 span: span.into_spans(),
465 }
466 }
467
468 impl core::default::Default for $name {
469 fn default() -> Self {
470 $name(Span::call_site())
471 }
472 }
473
474 #[cfg(feature = "clone-impls")]
475 #[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
476 impl Copy for $name {}
477
478 #[cfg(feature = "clone-impls")]
479 #[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
480 impl Clone for $name {
481 fn clone(&self) -> Self {
482 *self
483 }
484 }
485
486 #[cfg(feature = "extra-traits")]
487 #[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
488 impl Debug for $name {
489 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
490 f.write_str(stringify!($name))
491 }
492 }
493
494 #[cfg(feature = "extra-traits")]
495 #[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
496 impl cmp::Eq for $name {}
497
498 #[cfg(feature = "extra-traits")]
499 #[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
500 impl PartialEq for $name {
501 fn eq(&self, _other: &$name) -> bool {
502 true
503 }
504 }
505
506 #[cfg(feature = "extra-traits")]
507 #[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
508 impl Hash for $name {
509 fn hash<H: Hasher>(&self, _state: &mut H) {}
510 }
511
512 impl $name {
513 #[cfg(feature = "printing")]
514 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
515 pub fn surround<F>(&self, tokens: &mut TokenStream, f: F)
516 where
517 F: FnOnce(&mut TokenStream),
518 {
519 let mut inner = TokenStream::new();
520 f(&mut inner);
521 printing::delim(Delimiter::$delim, self.span.join(), tokens, inner);
522 }
523 }
524
525 #[cfg(feature = "parsing")]
526 impl private::Sealed for $name {}
527 )*
528 };
529}
530
531#[allow(unknown_lints, renamed_and_removed_lints,
repr_transparent_non_zst_fields,)]
#[doc = "`_`"]
#[doc =
" wildcard patterns, inferred types, unnamed items in constants, extern crates, use declarations, and destructuring assignment."]
pub struct Underscore {
pub spans: [Span; 1],
}
#[doc(hidden)]
#[allow(non_snake_case)]
pub fn Underscore<S: IntoSpans<[Span; 1]>>(spans: S) -> Underscore {
Underscore { spans: spans.into_spans() }
}
impl core::default::Default for Underscore {
fn default() -> Self { Underscore { spans: [Span::call_site(); 1] } }
}
#[doc(cfg(feature = "clone-impls"))]
impl Copy for Underscore { }
#[doc(cfg(feature = "clone-impls"))]
impl Clone for Underscore {
fn clone(&self) -> Self { *self }
}
#[doc(cfg(feature = "extra-traits"))]
impl Debug for Underscore {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
format_token(f, "_")
}
}
#[doc(cfg(feature = "extra-traits"))]
impl cmp::Eq for Underscore { }
#[doc(cfg(feature = "extra-traits"))]
impl PartialEq for Underscore {
fn eq(&self, _other: &Underscore) -> bool { true }
}
#[doc(cfg(feature = "extra-traits"))]
impl Hash for Underscore {
fn hash<H: Hasher>(&self, _state: &mut H) {}
}
impl Deref for Underscore {
type Target = WithSpan;
fn deref(&self) -> &Self::Target {
unsafe { &*(self as *const Self).cast::<WithSpan>() }
}
}
impl DerefMut for Underscore {
fn deref_mut(&mut self) -> &mut Self::Target {
unsafe { &mut *(self as *mut Self).cast::<WithSpan>() }
}
}define_punctuation_structs! {
532 "_" pub struct Underscore/1 }
534
535#[cfg(feature = "printing")]
536#[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
537impl ToTokens for Underscore {
538 fn to_tokens(&self, tokens: &mut TokenStream) {
539 tokens.append(Ident::new("_", self.span));
540 }
541}
542
543#[cfg(feature = "parsing")]
544#[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
545impl Parse for Underscore {
546 fn parse(input: ParseStream) -> Result<Self> {
547 input.step(|cursor| {
548 if let Some((ident, rest)) = cursor.ident() {
549 if ident == "_" {
550 return Ok((Underscore(ident.span()), rest));
551 }
552 }
553 if let Some((punct, rest)) = cursor.punct() {
554 if punct.as_char() == '_' {
555 return Ok((Underscore(punct.span()), rest));
556 }
557 }
558 Err(cursor.error("expected `_`"))
559 })
560 }
561}
562
563#[cfg(feature = "parsing")]
564impl Token for Underscore {
565 fn peek(cursor: Cursor) -> bool {
566 if let Some((ident, _rest)) = cursor.ident() {
567 return ident == "_";
568 }
569 if let Some((punct, _rest)) = cursor.punct() {
570 return punct.as_char() == '_';
571 }
572 false
573 }
574
575 fn display() -> &'static str {
576 "`_`"
577 }
578}
579
580#[cfg(feature = "parsing")]
581impl private::Sealed for Underscore {}
582
583pub struct Group {
585 pub span: Span,
586}
587
588#[doc(hidden)]
589#[allow(non_snake_case)]
590pub fn Group<S: IntoSpans<Span>>(span: S) -> Group {
591 Group {
592 span: span.into_spans(),
593 }
594}
595
596impl core::default::Default for Group {
597 fn default() -> Self {
598 Group {
599 span: Span::call_site(),
600 }
601 }
602}
603
604#[cfg(feature = "clone-impls")]
605#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
606impl Copy for Group {}
607
608#[cfg(feature = "clone-impls")]
609#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
610impl Clone for Group {
611 fn clone(&self) -> Self {
612 *self
613 }
614}
615
616#[cfg(feature = "extra-traits")]
617#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
618impl Debug for Group {
619 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
620 f.write_str("Group")
621 }
622}
623
624#[cfg(feature = "extra-traits")]
625#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
626impl cmp::Eq for Group {}
627
628#[cfg(feature = "extra-traits")]
629#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
630impl PartialEq for Group {
631 fn eq(&self, _other: &Group) -> bool {
632 true
633 }
634}
635
636#[cfg(feature = "extra-traits")]
637#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
638impl Hash for Group {
639 fn hash<H: Hasher>(&self, _state: &mut H) {}
640}
641
642impl Group {
643 #[cfg(feature = "printing")]
644 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
645 pub fn surround<F>(&self, tokens: &mut TokenStream, f: F)
646 where
647 F: FnOnce(&mut TokenStream),
648 {
649 let mut inner = TokenStream::new();
650 f(&mut inner);
651 printing::delim(Delimiter::None, self.span, tokens, inner);
652 }
653}
654
655#[cfg(feature = "parsing")]
656impl private::Sealed for Group {}
657
658#[cfg(feature = "parsing")]
659impl Token for Paren {
660 fn peek(cursor: Cursor) -> bool {
661 cursor.group(Delimiter::Parenthesis).is_some()
662 }
663
664 fn display() -> &'static str {
665 "parentheses"
666 }
667}
668
669#[cfg(feature = "parsing")]
670impl Token for Brace {
671 fn peek(cursor: Cursor) -> bool {
672 cursor.group(Delimiter::Brace).is_some()
673 }
674
675 fn display() -> &'static str {
676 "curly braces"
677 }
678}
679
680#[cfg(feature = "parsing")]
681impl Token for Bracket {
682 fn peek(cursor: Cursor) -> bool {
683 cursor.group(Delimiter::Bracket).is_some()
684 }
685
686 fn display() -> &'static str {
687 "square brackets"
688 }
689}
690
691#[cfg(feature = "parsing")]
692impl Token for Group {
693 fn peek(cursor: Cursor) -> bool {
694 cursor.group(Delimiter::None).is_some()
695 }
696
697 fn display() -> &'static str {
698 "invisible group"
699 }
700}
701
702#[doc = "`yield`"]
pub struct Yield {
pub span: Span,
}
#[doc(hidden)]
#[allow(non_snake_case)]
pub fn Yield<S: IntoSpans<Span>>(span: S) -> Yield {
Yield { span: span.into_spans() }
}
impl core::default::Default for Yield {
fn default() -> Self { Yield { span: Span::call_site() } }
}
#[doc(cfg(feature = "clone-impls"))]
impl Copy for Yield { }
#[doc(cfg(feature = "clone-impls"))]
impl Clone for Yield {
fn clone(&self) -> Self { *self }
}
#[doc(cfg(feature = "extra-traits"))]
impl Debug for Yield {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
format_token(f, "yield")
}
}
#[doc(cfg(feature = "extra-traits"))]
impl cmp::Eq for Yield { }
#[doc(cfg(feature = "extra-traits"))]
impl PartialEq for Yield {
fn eq(&self, _other: &Yield) -> bool { true }
}
#[doc(cfg(feature = "extra-traits"))]
impl Hash for Yield {
fn hash<H: Hasher>(&self, _state: &mut H) {}
}
#[doc(cfg(feature = "printing"))]
impl ToTokens for Yield {
fn to_tokens(&self, tokens: &mut TokenStream) {
printing::keyword("yield", self.span, tokens);
}
}
#[doc(cfg(feature = "parsing"))]
impl Parse for Yield {
fn parse(input: ParseStream) -> Result<Self> {
Ok(Yield { span: parsing::keyword(input, "yield")? })
}
}
impl Token for Yield {
fn peek(cursor: Cursor) -> bool { cursor.peek_keyword("yield") }
fn display() -> &'static str { "`yield`" }
}
impl private::Sealed for Yield { }define_keywords! {
703 "abstract" pub struct Abstract
704 "as" pub struct As
705 "async" pub struct Async
706 "auto" pub struct Auto
707 "await" pub struct Await
708 "become" pub struct Become
709 "box" pub struct Box
710 "break" pub struct Break
711 "const" pub struct Const
712 "continue" pub struct Continue
713 "crate" pub struct Crate
714 "default" pub struct Default
715 "do" pub struct Do
716 "dyn" pub struct Dyn
717 "else" pub struct Else
718 "enum" pub struct Enum
719 "extern" pub struct Extern
720 "final" pub struct Final
721 "fn" pub struct Fn
722 "for" pub struct For
723 "if" pub struct If
724 "impl" pub struct Impl
725 "in" pub struct In
726 "let" pub struct Let
727 "loop" pub struct Loop
728 "macro" pub struct Macro
729 "match" pub struct Match
730 "mod" pub struct Mod
731 "move" pub struct Move
732 "mut" pub struct Mut
733 "override" pub struct Override
734 "priv" pub struct Priv
735 "pub" pub struct Pub
736 "raw" pub struct Raw
737 "ref" pub struct Ref
738 "return" pub struct Return
739 "safe" pub struct Safe
740 "Self" pub struct SelfType
741 "self" pub struct SelfValue
742 "static" pub struct Static
743 "struct" pub struct Struct
744 "super" pub struct Super
745 "trait" pub struct Trait
746 "try" pub struct Try
747 "type" pub struct Type
748 "typeof" pub struct Typeof
749 "union" pub struct Union
750 "unsafe" pub struct Unsafe
751 "unsized" pub struct Unsized
752 "use" pub struct Use
753 "virtual" pub struct Virtual
754 "where" pub struct Where
755 "while" pub struct While
756 "yield" pub struct Yield
757}
758
759impl Deref for Tilde {
type Target = WithSpan;
fn deref(&self) -> &Self::Target {
unsafe { &*(self as *const Self).cast::<WithSpan>() }
}
}
impl DerefMut for Tilde {
fn deref_mut(&mut self) -> &mut Self::Target {
unsafe { &mut *(self as *mut Self).cast::<WithSpan>() }
}
}
#[doc(cfg(feature = "printing"))]
impl ToTokens for Tilde {
fn to_tokens(&self, tokens: &mut TokenStream) {
printing::punct("~", &self.spans, tokens);
}
}
#[doc(cfg(feature = "parsing"))]
impl Parse for Tilde {
fn parse(input: ParseStream) -> Result<Self> {
Ok(Tilde { spans: parsing::punct(input, "~")? })
}
}
impl Token for Tilde {
fn peek(cursor: Cursor) -> bool { cursor.peek_punct("~") }
fn display() -> &'static str { "`~`" }
}
impl private::Sealed for Tilde { }define_punctuation! {
760 "&" pub struct And/1 "&&" pub struct AndAnd/2 "&=" pub struct AndEq/2 "@" pub struct At/1 "^" pub struct Caret/1 "^=" pub struct CaretEq/2 ":" pub struct Colon/1 "," pub struct Comma/1 "$" pub struct Dollar/1 "." pub struct Dot/1 ".." pub struct DotDot/2 "..." pub struct DotDotDot/3 "..=" pub struct DotDotEq/3 "=" pub struct Eq/1 "==" pub struct EqEq/2 "=>" pub struct FatArrow/2 ">=" pub struct Ge/2 ">" pub struct Gt/1 "<-" pub struct LArrow/2 "<=" pub struct Le/2 "<" pub struct Lt/1 "-" pub struct Minus/1 "-=" pub struct MinusEq/2 "!=" pub struct Ne/2 "!" pub struct Not/1 "|" pub struct Or/1 "|=" pub struct OrEq/2 "||" pub struct OrOr/2 "::" pub struct PathSep/2 "%" pub struct Percent/1 "%=" pub struct PercentEq/2 "+" pub struct Plus/1 "+=" pub struct PlusEq/2 "#" pub struct Pound/1 "?" pub struct Question/1 "->" pub struct RArrow/2 ";" pub struct Semi/1 "<<" pub struct Shl/2 "<<=" pub struct ShlEq/3 ">>" pub struct Shr/2 ">>=" pub struct ShrEq/3 "/" pub struct Slash/1 "/=" pub struct SlashEq/2 "*" pub struct Star/1 "*=" pub struct StarEq/2 "~" pub struct Tilde/1 }
807
808#[doc = r" `(`…`)`"]
pub struct Paren {
pub span: DelimSpan,
}
#[doc(hidden)]
#[allow(non_snake_case)]
pub fn Paren<S: IntoSpans<DelimSpan>>(span: S) -> Paren {
Paren { span: span.into_spans() }
}
impl core::default::Default for Paren {
fn default() -> Self { Paren(Span::call_site()) }
}
#[doc(cfg(feature = "clone-impls"))]
impl Copy for Paren { }
#[doc(cfg(feature = "clone-impls"))]
impl Clone for Paren {
fn clone(&self) -> Self { *self }
}
#[doc(cfg(feature = "extra-traits"))]
impl Debug for Paren {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_str("Paren")
}
}
#[doc(cfg(feature = "extra-traits"))]
impl cmp::Eq for Paren { }
#[doc(cfg(feature = "extra-traits"))]
impl PartialEq for Paren {
fn eq(&self, _other: &Paren) -> bool { true }
}
#[doc(cfg(feature = "extra-traits"))]
impl Hash for Paren {
fn hash<H: Hasher>(&self, _state: &mut H) {}
}
impl Paren {
#[doc(cfg(feature = "printing"))]
pub fn surround<F>(&self, tokens: &mut TokenStream, f: F) where
F: FnOnce(&mut TokenStream) {
let mut inner = TokenStream::new();
f(&mut inner);
printing::delim(Delimiter::Parenthesis, self.span.join(), tokens,
inner);
}
}
impl private::Sealed for Paren { }define_delimiters! {
809 Brace pub struct Brace Bracket pub struct Bracket Parenthesis pub struct Paren }
813
814#[macro_export]
882macro_rules! Token {
883 [abstract] => { $crate::token::Abstract };
884 [as] => { $crate::token::As };
885 [async] => { $crate::token::Async };
886 [auto] => { $crate::token::Auto };
887 [await] => { $crate::token::Await };
888 [become] => { $crate::token::Become };
889 [box] => { $crate::token::Box };
890 [break] => { $crate::token::Break };
891 [const] => { $crate::token::Const };
892 [continue] => { $crate::token::Continue };
893 [crate] => { $crate::token::Crate };
894 [default] => { $crate::token::Default };
895 [do] => { $crate::token::Do };
896 [dyn] => { $crate::token::Dyn };
897 [else] => { $crate::token::Else };
898 [enum] => { $crate::token::Enum };
899 [extern] => { $crate::token::Extern };
900 [final] => { $crate::token::Final };
901 [fn] => { $crate::token::Fn };
902 [for] => { $crate::token::For };
903 [if] => { $crate::token::If };
904 [impl] => { $crate::token::Impl };
905 [in] => { $crate::token::In };
906 [let] => { $crate::token::Let };
907 [loop] => { $crate::token::Loop };
908 [macro] => { $crate::token::Macro };
909 [match] => { $crate::token::Match };
910 [mod] => { $crate::token::Mod };
911 [move] => { $crate::token::Move };
912 [mut] => { $crate::token::Mut };
913 [override] => { $crate::token::Override };
914 [priv] => { $crate::token::Priv };
915 [pub] => { $crate::token::Pub };
916 [raw] => { $crate::token::Raw };
917 [ref] => { $crate::token::Ref };
918 [return] => { $crate::token::Return };
919 [safe] => { $crate::token::Safe };
920 [Self] => { $crate::token::SelfType };
921 [self] => { $crate::token::SelfValue };
922 [static] => { $crate::token::Static };
923 [struct] => { $crate::token::Struct };
924 [super] => { $crate::token::Super };
925 [trait] => { $crate::token::Trait };
926 [try] => { $crate::token::Try };
927 [type] => { $crate::token::Type };
928 [typeof] => { $crate::token::Typeof };
929 [union] => { $crate::token::Union };
930 [unsafe] => { $crate::token::Unsafe };
931 [unsized] => { $crate::token::Unsized };
932 [use] => { $crate::token::Use };
933 [virtual] => { $crate::token::Virtual };
934 [where] => { $crate::token::Where };
935 [while] => { $crate::token::While };
936 [yield] => { $crate::token::Yield };
937 [&] => { $crate::token::And };
938 [&&] => { $crate::token::AndAnd };
939 [&=] => { $crate::token::AndEq };
940 [@] => { $crate::token::At };
941 [^] => { $crate::token::Caret };
942 [^=] => { $crate::token::CaretEq };
943 [:] => { $crate::token::Colon };
944 [,] => { $crate::token::Comma };
945 [$] => { $crate::token::Dollar };
946 [.] => { $crate::token::Dot };
947 [..] => { $crate::token::DotDot };
948 [...] => { $crate::token::DotDotDot };
949 [..=] => { $crate::token::DotDotEq };
950 [=] => { $crate::token::Eq };
951 [==] => { $crate::token::EqEq };
952 [=>] => { $crate::token::FatArrow };
953 [>=] => { $crate::token::Ge };
954 [>] => { $crate::token::Gt };
955 [<-] => { $crate::token::LArrow };
956 [<=] => { $crate::token::Le };
957 [<] => { $crate::token::Lt };
958 [-] => { $crate::token::Minus };
959 [-=] => { $crate::token::MinusEq };
960 [!=] => { $crate::token::Ne };
961 [!] => { $crate::token::Not };
962 [|] => { $crate::token::Or };
963 [|=] => { $crate::token::OrEq };
964 [||] => { $crate::token::OrOr };
965 [::] => { $crate::token::PathSep };
966 [%] => { $crate::token::Percent };
967 [%=] => { $crate::token::PercentEq };
968 [+] => { $crate::token::Plus };
969 [+=] => { $crate::token::PlusEq };
970 [#] => { $crate::token::Pound };
971 [?] => { $crate::token::Question };
972 [->] => { $crate::token::RArrow };
973 [;] => { $crate::token::Semi };
974 [<<] => { $crate::token::Shl };
975 [<<=] => { $crate::token::ShlEq };
976 [>>] => { $crate::token::Shr };
977 [>>=] => { $crate::token::ShrEq };
978 [/] => { $crate::token::Slash };
979 [/=] => { $crate::token::SlashEq };
980 [*] => { $crate::token::Star };
981 [*=] => { $crate::token::StarEq };
982 [~] => { $crate::token::Tilde };
983 [_] => { $crate::token::Underscore };
984}
985
986#[cfg(feature = "extra-traits")]
987fn format_token(formatter: &mut fmt::Formatter, repr: &str) -> fmt::Result {
988 formatter.write_fmt(format_args!("Token![{0}]", repr))write!(formatter, "Token![{}]", repr)
989}
990
991#[doc(hidden)]
993#[cfg(feature = "parsing")]
994pub(crate) mod parsing {
995 use crate::buffer::Cursor;
996 use crate::error::{Error, Result};
997 use crate::parse::ParseStream;
998 use alloc::format;
999 use proc_macro2::{Spacing, Span};
1000
1001 pub(crate) fn keyword(input: ParseStream, token: &str) -> Result<Span> {
1002 input.step(|cursor| {
1003 if let Some((ident, rest)) = cursor.ident() {
1004 if ident == token {
1005 return Ok((ident.span(), rest));
1006 }
1007 }
1008 Err(cursor.error(::alloc::__export::must_use({
::alloc::fmt::format(format_args!("expected `{0}`", token))
})format!("expected `{}`", token)))
1009 })
1010 }
1011
1012 #[doc(hidden)]
1013 pub fn punct<const N: usize>(input: ParseStream, token: &str) -> Result<[Span; N]> {
1014 let mut spans = [input.span(); N];
1015 punct_helper(input, token, &mut spans)?;
1016 Ok(spans)
1017 }
1018
1019 fn punct_helper(input: ParseStream, token: &str, spans: &mut [Span]) -> Result<()> {
1020 input.step(|cursor| {
1021 let mut cursor = *cursor;
1022 {
match (&token.len(), &spans.len()) {
(left_val, right_val) => {
if !(*left_val == *right_val) {
let kind = ::core::panicking::AssertKind::Eq;
::core::panicking::assert_failed(kind, &*left_val,
&*right_val, ::core::option::Option::None);
}
}
}
};assert_eq!(token.len(), spans.len());
1023
1024 for (i, ch) in token.chars().enumerate() {
1025 match cursor.punct() {
1026 Some((punct, rest)) => {
1027 spans[i] = punct.span();
1028 if punct.as_char() != ch {
1029 break;
1030 } else if i == token.len() - 1 {
1031 return Ok(((), rest));
1032 } else if punct.spacing() != Spacing::Joint {
1033 break;
1034 }
1035 cursor = rest;
1036 }
1037 None => break,
1038 }
1039 }
1040
1041 Err(Error::new(spans[0], ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("expected `{0}`", token))
})format!("expected `{}`", token)))
1042 })
1043 }
1044
1045 #[doc(hidden)]
1046 pub fn peek_punct(mut cursor: Cursor, token: &str) -> bool {
1047 for (i, ch) in token.chars().enumerate() {
1048 match cursor.punct() {
1049 Some((punct, rest)) => {
1050 if punct.as_char() != ch {
1051 break;
1052 } else if i == token.len() - 1 {
1053 return true;
1054 } else if punct.spacing() != Spacing::Joint {
1055 break;
1056 }
1057 cursor = rest;
1058 }
1059 None => break,
1060 }
1061 }
1062 false
1063 }
1064}
1065
1066#[doc(hidden)]
1068#[cfg(feature = "printing")]
1069pub(crate) mod printing {
1070 use crate::ext::PunctExt as _;
1071 use proc_macro2::{Delimiter, Group, Ident, Punct, Spacing, Span, TokenStream};
1072 use quote::TokenStreamExt as _;
1073
1074 #[doc(hidden)]
1075 pub fn punct(s: &str, spans: &[Span], tokens: &mut TokenStream) {
1076 {
match (&s.len(), &spans.len()) {
(left_val, right_val) => {
if !(*left_val == *right_val) {
let kind = ::core::panicking::AssertKind::Eq;
::core::panicking::assert_failed(kind, &*left_val,
&*right_val, ::core::option::Option::None);
}
}
}
};assert_eq!(s.len(), spans.len());
1077
1078 let mut chars = s.chars();
1079 let mut spans = spans.iter();
1080 let ch = chars.next_back().unwrap();
1081 let span = spans.next_back().unwrap();
1082 for (ch, span) in chars.zip(spans) {
1083 tokens.append(Punct::new_spanned(ch, Spacing::Joint, *span));
1084 }
1085
1086 tokens.append(Punct::new_spanned(ch, Spacing::Alone, *span));
1087 }
1088
1089 pub(crate) fn keyword(s: &str, span: Span, tokens: &mut TokenStream) {
1090 tokens.append(Ident::new(s, span));
1091 }
1092
1093 pub(crate) fn delim(
1094 delim: Delimiter,
1095 span: Span,
1096 tokens: &mut TokenStream,
1097 inner: TokenStream,
1098 ) {
1099 let mut g = Group::new(delim, inner);
1100 g.set_span(span);
1101 tokens.append(g);
1102 }
1103}