1 #![allow(clippy::items_after_statements, clippy::let_underscore_untyped)]
2
3 use proc_macro2::{Delimiter, Group, Punct, Spacing, Span, TokenStream, TokenTree};
4 use quote::quote;
5 use syn::ext::IdentExt as _;
6 use syn::parse::discouraged::AnyDelimiter;
7 use syn::parse::{ParseStream, Parser as _, Result};
8 use syn::{parenthesized, token, Ident, Lifetime, Token};
9
10 #[test]
test_peek_punct()11 fn test_peek_punct() {
12 let tokens = quote!(+= + =);
13
14 fn assert(input: ParseStream) -> Result<()> {
15 assert!(input.peek(Token![+]));
16 assert!(input.peek(Token![+=]));
17
18 let _: Token![+] = input.parse()?;
19
20 assert!(input.peek(Token![=]));
21 assert!(!input.peek(Token![==]));
22 assert!(!input.peek(Token![+]));
23
24 let _: Token![=] = input.parse()?;
25
26 assert!(input.peek(Token![+]));
27 assert!(!input.peek(Token![+=]));
28
29 let _: Token![+] = input.parse()?;
30 let _: Token![=] = input.parse()?;
31 Ok(())
32 }
33
34 assert.parse2(tokens).unwrap();
35 }
36
37 #[test]
test_peek_lifetime()38 fn test_peek_lifetime() {
39 // 'static ;
40 let tokens = TokenStream::from_iter([
41 TokenTree::Punct(Punct::new('\'', Spacing::Joint)),
42 TokenTree::Ident(Ident::new("static", Span::call_site())),
43 TokenTree::Punct(Punct::new(';', Spacing::Alone)),
44 ]);
45
46 fn assert(input: ParseStream) -> Result<()> {
47 assert!(input.peek(Lifetime));
48 assert!(input.peek2(Token![;]));
49 assert!(!input.peek2(Token![static]));
50
51 let _: Lifetime = input.parse()?;
52
53 assert!(input.peek(Token![;]));
54
55 let _: Token![;] = input.parse()?;
56 Ok(())
57 }
58
59 assert.parse2(tokens).unwrap();
60 }
61
62 #[test]
test_peek_not_lifetime()63 fn test_peek_not_lifetime() {
64 // ' static
65 let tokens = TokenStream::from_iter([
66 TokenTree::Punct(Punct::new('\'', Spacing::Alone)),
67 TokenTree::Ident(Ident::new("static", Span::call_site())),
68 ]);
69
70 fn assert(input: ParseStream) -> Result<()> {
71 assert!(!input.peek(Lifetime));
72 assert!(input.parse::<Option<Punct>>()?.is_none());
73
74 let _: TokenTree = input.parse()?;
75
76 assert!(input.peek(Token![static]));
77
78 let _: Token![static] = input.parse()?;
79 Ok(())
80 }
81
82 assert.parse2(tokens).unwrap();
83 }
84
85 #[test]
test_peek_ident()86 fn test_peek_ident() {
87 let tokens = quote!(static var);
88
89 fn assert(input: ParseStream) -> Result<()> {
90 assert!(!input.peek(Ident));
91 assert!(input.peek(Ident::peek_any));
92 assert!(input.peek(Token![static]));
93
94 let _: Token![static] = input.parse()?;
95
96 assert!(input.peek(Ident));
97 assert!(input.peek(Ident::peek_any));
98
99 let _: Ident = input.parse()?;
100 Ok(())
101 }
102
103 assert.parse2(tokens).unwrap();
104 }
105
106 #[test]
test_peek_groups()107 fn test_peek_groups() {
108 // pub ( :: ) «∅ ! = ∅» static
109 let tokens = TokenStream::from_iter([
110 TokenTree::Ident(Ident::new("pub", Span::call_site())),
111 TokenTree::Group(Group::new(
112 Delimiter::Parenthesis,
113 TokenStream::from_iter([
114 TokenTree::Punct(Punct::new(':', Spacing::Joint)),
115 TokenTree::Punct(Punct::new(':', Spacing::Alone)),
116 ]),
117 )),
118 TokenTree::Group(Group::new(
119 Delimiter::None,
120 TokenStream::from_iter([
121 TokenTree::Punct(Punct::new('!', Spacing::Alone)),
122 TokenTree::Punct(Punct::new('=', Spacing::Alone)),
123 ]),
124 )),
125 TokenTree::Ident(Ident::new("static", Span::call_site())),
126 ]);
127
128 fn assert(input: ParseStream) -> Result<()> {
129 assert!(input.peek2(token::Paren));
130 assert!(input.peek3(token::Group));
131 assert!(input.peek3(Token![!]));
132
133 let _: Token![pub] = input.parse()?;
134
135 assert!(input.peek(token::Paren));
136 assert!(!input.peek(Token![::]));
137 assert!(!input.peek2(Token![::]));
138 assert!(input.peek2(Token![!]));
139 assert!(input.peek2(token::Group));
140 assert!(input.peek3(Token![=]));
141 assert!(!input.peek3(Token![static]));
142
143 let content;
144 parenthesized!(content in input);
145
146 assert!(content.peek(Token![::]));
147 assert!(content.peek2(Token![:]));
148 assert!(!content.peek3(token::Group));
149 assert!(!content.peek3(Token![!]));
150
151 assert!(input.peek(token::Group));
152 assert!(input.peek(Token![!]));
153
154 let _: Token![::] = content.parse()?;
155
156 assert!(input.peek(token::Group));
157 assert!(input.peek(Token![!]));
158 assert!(input.peek2(Token![=]));
159 assert!(input.peek3(Token![static]));
160 assert!(!input.peek2(Token![static]));
161
162 let implicit = input.fork();
163 let explicit = input.fork();
164
165 let _: Token![!] = implicit.parse()?;
166 assert!(implicit.peek(Token![=]));
167 assert!(implicit.peek2(Token![static]));
168 let _: Token![=] = implicit.parse()?;
169 assert!(implicit.peek(Token![static]));
170
171 let (delimiter, _span, grouped) = explicit.parse_any_delimiter()?;
172 assert_eq!(delimiter, Delimiter::None);
173 assert!(grouped.peek(Token![!]));
174 assert!(grouped.peek2(Token![=]));
175 assert!(!grouped.peek3(Token![static]));
176 let _: Token![!] = grouped.parse()?;
177 assert!(grouped.peek(Token![=]));
178 assert!(!grouped.peek2(Token![static]));
179 let _: Token![=] = grouped.parse()?;
180 assert!(!grouped.peek(Token![static]));
181
182 let _: TokenStream = input.parse()?;
183 Ok(())
184 }
185
186 assert.parse2(tokens).unwrap();
187 }
188