1#![doc = include_str!("../README.md")]
2
3extern crate alloc;
4
5use ::alloc::vec::Vec;
6use ::core::{
7 fmt::Debug,
8 ops::{
9 Deref,
10 DerefMut,
11 },
12};
13use ::proc_macro2::{
14 Delimiter,
15 Group,
16 Ident,
17 Literal,
18 Punct,
19 Span,
20 TokenStream,
21 TokenTree,
22 extra::DelimSpan,
23};
24
25#[derive(Clone, Debug)]
33pub struct GroupWithMetadata<G, I = G, P = G, L = I> {
34 pub delimiter: Delimiter,
36 pub contents: TokenWithMetadataVec<G, I, P, L>,
39 pub span: Span,
42 pub metadata: G,
44}
45
46impl<G, I, P, L> GroupWithMetadata<G, I, P, L> {
47 #[must_use = "If you meant to drop this value, use `std::mem::drop` instead."]
52 pub fn strip_metadata(self) -> Group {
53 let mut group = Group::new(
54 self.delimiter,
55 token_with_metadata_iter_ext::iter_tokens_strip_metadata(self.contents).collect(),
56 );
57 group.set_span(self.span);
58 group
59 }
60
61 #[inline(always)]
63 #[deprecated(note = "Use the `delimiter` field directly.")]
64 pub fn delimiter(&self) -> Delimiter {
65 self.delimiter
66 }
67
68 #[inline(always)]
70 #[must_use]
71 #[deprecated(note = "Use the `span` field directly.")]
72 pub fn span(&self) -> Span {
73 self.span
74 }
75
76 #[must_use]
78 pub fn span_open(&self) -> Span {
79 let mut dummy = Group::new(self.delimiter, TokenStream::new());
82 dummy.set_span(self.span);
83 dummy.span_open()
84 }
85
86 #[must_use]
88 pub fn span_close(&self) -> Span {
89 let mut dummy = Group::new(self.delimiter, TokenStream::new());
90 dummy.set_span(self.span);
91 dummy.span_close()
92 }
93
94 #[must_use]
96 pub fn delim_span(&self) -> DelimSpan {
97 let mut dummy = Group::new(self.delimiter, TokenStream::new());
98 dummy.set_span(self.span);
99 dummy.delim_span()
100 }
101
102 #[inline(always)]
104 #[deprecated(note = "Use the `span` field directly.")]
105 pub fn set_span(&mut self, span: Span) {
106 self.span = span;
107 }
108}
109
110impl<G, I, P, L> From<Group> for GroupWithMetadata<G, I, P, L>
111where
112 G: Default,
113 I: Default,
114 P: Default,
115 L: Default,
116{
117 fn from(value: Group) -> Self {
118 Self {
119 delimiter: value.delimiter(),
120 contents: token_with_metadata_iter_ext::iter_tokens_add_default_metadata(value.stream()).collect(),
121 span: value.span(),
122 metadata: G::default(),
123 }
124 }
125}
126
127impl<T> From<(Group, &T)> for GroupWithMetadata<T>
128where
129 T: Clone,
130{
131 fn from((value, metadata): (Group, &T)) -> Self {
132 Self {
133 delimiter: value.delimiter(),
134 contents: token_with_metadata_iter_ext::iter_tokens_add_metadata(value.stream(), metadata).collect(),
135 span: value.span(),
136 metadata: metadata.clone(),
137 }
138 }
139}
140
141impl<G, I, P, L> From<(Group, &G, &I, &P, &L)> for GroupWithMetadata<G, I, P, L>
142where
143 G: Clone,
144 I: Clone,
145 P: Clone,
146 L: Clone,
147{
148 fn from((value, g, i, p, l): (Group, &G, &I, &P, &L)) -> Self {
149 Self {
150 delimiter: value.delimiter(),
151 contents: token_with_metadata_iter_ext::iter_tokens_add_specific_metadata(value.stream(), g, i, p, l).collect(),
152 span: value.span(),
153 metadata: g.clone(),
154 }
155 }
156}
157
158#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)]
166pub struct TokenWithMetadata<T, U> {
167 pub token: T,
169 pub metadata: U,
171}
172
173impl<T, U> Deref for TokenWithMetadata<T, U> {
175 type Target = T;
176
177 #[inline(always)]
178 fn deref(&self) -> &Self::Target {
179 &self.token
180 }
181}
182
183impl<T, U> DerefMut for TokenWithMetadata<T, U> {
185 #[inline(always)]
186 fn deref_mut(&mut self) -> &mut Self::Target {
187 &mut self.token
188 }
189}
190
191impl<T, U: Default> From<T> for TokenWithMetadata<T, U> {
192 #[inline(always)]
193 fn from(token: T) -> Self {
194 Self { token, metadata: U::default() }
195 }
196}
197
198impl<T, U> From<(T, U)> for TokenWithMetadata<T, U> {
199 #[inline(always)]
200 fn from((token, metadata): (T, U)) -> Self {
201 Self { token, metadata }
202 }
203}
204
205#[derive(Clone, Debug)]
215pub enum TokenTreeWithMetadata<G, I = G, P = G, L = I> {
216 Group(GroupWithMetadata<G, I, P, L>),
220 Ident(TokenWithMetadata<Ident, I>),
222 Punct(TokenWithMetadata<Punct, P>),
224 Literal(TokenWithMetadata<Literal, L>),
226}
227
228impl<G, I, P, L> TokenTreeWithMetadata<G, I, P, L> {
229 #[inline]
233 #[must_use = "If you meant to drop this value, use `std::mem::drop` instead."]
234 pub fn strip_metadata(self) -> TokenTree {
235 match self {
236 | TokenTreeWithMetadata::Group(group) => TokenTree::Group(group.strip_metadata()),
237 | TokenTreeWithMetadata::Ident(twm) => TokenTree::Ident(twm.token),
238 | TokenTreeWithMetadata::Punct(twm) => TokenTree::Punct(twm.token),
239 | TokenTreeWithMetadata::Literal(twm) => TokenTree::Literal(twm.token),
240 }
241 }
242
243 #[inline]
247 #[must_use]
248 pub fn span(&self) -> Span {
249 match self {
250 | TokenTreeWithMetadata::Group(group) => group.span,
251 | TokenTreeWithMetadata::Ident(twm) => twm.token.span(),
252 | TokenTreeWithMetadata::Punct(twm) => twm.token.span(),
253 | TokenTreeWithMetadata::Literal(twm) => twm.token.span(),
254 }
255 }
256
257 #[inline]
261 pub fn set_span(&mut self, span: Span) {
262 match self {
263 | TokenTreeWithMetadata::Group(group) => group.span = span,
264 | TokenTreeWithMetadata::Ident(twm) => twm.token.set_span(span),
265 | TokenTreeWithMetadata::Punct(twm) => twm.token.set_span(span),
266 | TokenTreeWithMetadata::Literal(twm) => twm.token.set_span(span),
267 }
268 }
269}
270
271impl<T> TokenTreeWithMetadata<T> {
272 #[inline]
275 #[must_use = "If you meant to drop this value, use `std::mem::drop` instead."]
276 pub fn get_metadata(self) -> T {
277 match self {
278 | Self::Group(group) => group.metadata,
279 | Self::Ident(twm) => twm.metadata,
280 | Self::Punct(twm) => twm.metadata,
281 | Self::Literal(twm) => twm.metadata,
282 }
283 }
284
285 #[inline]
288 #[must_use]
289 pub fn get_metadata_ref(&self) -> &T {
290 match self {
291 | Self::Group(group) => &group.metadata,
292 | Self::Ident(twm) => &twm.metadata,
293 | Self::Punct(twm) => &twm.metadata,
294 | Self::Literal(twm) => &twm.metadata,
295 }
296 }
297
298 #[inline]
301 #[must_use]
302 pub fn get_metadata_mut(&mut self) -> &mut T {
303 match self {
304 | Self::Group(group) => &mut group.metadata,
305 | Self::Ident(twm) => &mut twm.metadata,
306 | Self::Punct(twm) => &mut twm.metadata,
307 | Self::Literal(twm) => &mut twm.metadata,
308 }
309 }
310
311 #[inline]
314 pub fn set_metadata(&mut self, metadata: T) {
315 match self {
316 | Self::Group(group) => group.metadata = metadata,
317 | Self::Ident(twm) => twm.metadata = metadata,
318 | Self::Punct(twm) => twm.metadata = metadata,
319 | Self::Literal(twm) => twm.metadata = metadata,
320 }
321 }
322}
323
324impl<G, I, P, L> From<TokenTree> for TokenTreeWithMetadata<G, I, P, L>
325where
326 G: Default,
327 I: Default,
328 P: Default,
329 L: Default,
330{
331 #[inline]
332 fn from(tree: TokenTree) -> Self {
333 match tree {
334 | TokenTree::Group(group) => Self::Group(group.into()),
335 | TokenTree::Ident(ident) => Self::Ident(ident.into()),
336 | TokenTree::Punct(punct) => Self::Punct(punct.into()),
337 | TokenTree::Literal(literal) => Self::Literal(literal.into()),
338 }
339 }
340}
341
342impl<T> From<(TokenTree, &T)> for TokenTreeWithMetadata<T>
343where
344 T: Clone,
345{
346 #[inline]
347 fn from((tree, metadata): (TokenTree, &T)) -> Self {
348 match tree {
349 | TokenTree::Group(group) => Self::Group((group, metadata).into()),
350 | TokenTree::Ident(ident) => Self::Ident((ident, metadata.clone()).into()),
351 | TokenTree::Punct(punct) => Self::Punct((punct, metadata.clone()).into()),
352 | TokenTree::Literal(literal) => Self::Literal((literal, metadata.clone()).into()),
353 }
354 }
355}
356
357impl<G, I, P, L> From<(TokenTree, &G, &I, &P, &L)> for TokenTreeWithMetadata<G, I, P, L>
358where
359 G: Clone,
360 I: Clone,
361 P: Clone,
362 L: Clone,
363{
364 #[inline]
365 fn from((tree, g, i, p, l): (TokenTree, &G, &I, &P, &L)) -> Self {
366 match tree {
367 | TokenTree::Group(group) => Self::Group((group, g, i, p, l).into()),
368 | TokenTree::Ident(ident) => Self::Ident((ident, i.clone()).into()),
369 | TokenTree::Punct(punct) => Self::Punct((punct, p.clone()).into()),
370 | TokenTree::Literal(literal) => Self::Literal((literal, l.clone()).into()),
371 }
372 }
373}
374
375impl<G, I, P, L> From<Group> for TokenTreeWithMetadata<G, I, P, L>
376where
377 G: Default,
378 I: Default,
379 P: Default,
380 L: Default,
381{
382 #[inline(always)]
383 fn from(group: Group) -> Self {
384 Self::Group(group.into())
385 }
386}
387
388impl<T> From<(Group, &T)> for TokenTreeWithMetadata<T>
389where
390 T: Clone,
391{
392 #[inline(always)]
393 fn from(group_and_val: (Group, &T)) -> Self {
394 Self::Group(group_and_val.into())
395 }
396}
397
398impl<G, I, P, L> From<(Group, &G, &I, &P, &L)> for TokenTreeWithMetadata<G, I, P, L>
399where
400 G: Clone,
401 I: Clone,
402 P: Clone,
403 L: Clone,
404{
405 #[inline(always)]
406 fn from(group_and_vals: (Group, &G, &I, &P, &L)) -> Self {
407 Self::Group(group_and_vals.into())
408 }
409}
410
411impl<G, I, P, L> From<Ident> for TokenTreeWithMetadata<G, I, P, L>
412where
413 I: Default,
414{
415 #[inline(always)]
416 fn from(ident: Ident) -> Self {
417 Self::Ident(ident.into())
418 }
419}
420
421impl<G, I, P, L> From<(Ident, I)> for TokenTreeWithMetadata<G, I, P, L> {
422 #[inline(always)]
423 fn from((ident, metadata): (Ident, I)) -> Self {
424 Self::Ident((ident, metadata).into())
425 }
426}
427
428impl<G, I, P, L> From<Punct> for TokenTreeWithMetadata<G, I, P, L>
429where
430 P: Default,
431{
432 #[inline(always)]
433 fn from(punct: Punct) -> Self {
434 Self::Punct(punct.into())
435 }
436}
437
438impl<G, I, P, L> From<(Punct, P)> for TokenTreeWithMetadata<G, I, P, L> {
439 #[inline(always)]
440 fn from((punct, metadata): (Punct, P)) -> Self {
441 Self::Punct((punct, metadata).into())
442 }
443}
444
445impl<G, I, P, L> From<Literal> for TokenTreeWithMetadata<G, I, P, L>
446where
447 L: Default,
448{
449 #[inline(always)]
450 fn from(literal: Literal) -> Self {
451 Self::Literal(literal.into())
452 }
453}
454
455impl<G, I, P, L> From<(Literal, L)> for TokenTreeWithMetadata<G, I, P, L> {
456 #[inline(always)]
457 fn from((literal, metadata): (Literal, L)) -> Self {
458 Self::Literal((literal, metadata).into())
459 }
460}
461
462pub type TokenWithMetadataVec<G, I = G, P = G, L = I> = Vec<TokenTreeWithMetadata<G, I, P, L>>;
469
470pub mod token_with_metadata_iter_ext {
473 use super::*;
474
475 pub fn iter_tokens_strip_metadata<G, I, P, L>(iter: impl IntoIterator<Item = TokenTreeWithMetadata<G, I, P, L>>) -> impl Iterator<Item = TokenTree> {
478 iter.into_iter().map(|ttwm| ttwm.strip_metadata())
479 }
480
481 pub fn iter_tokens_add_default_metadata<G, I, P, L>(iter: impl IntoIterator<Item = TokenTree>) -> impl Iterator<Item = TokenTreeWithMetadata<G, I, P, L>>
484 where
485 G: Default,
486 I: Default,
487 P: Default,
488 L: Default,
489 {
490 iter.into_iter().map(|tt| tt.into())
491 }
492
493 pub fn iter_tokens_add_metadata<T>(iter: impl IntoIterator<Item = TokenTree>, metadata: &T) -> impl Iterator<Item = TokenTreeWithMetadata<T>>
496 where
497 T: Clone,
498 {
499 iter.into_iter().map(move |tt| (tt, metadata).into())
500 }
501
502 pub fn iter_tokens_add_specific_metadata<G, I, P, L>(
506 iter: impl IntoIterator<Item = TokenTree>,
507 group: &G,
508 ident: &I,
509 punct: &P,
510 literal: &L,
511 ) -> impl Iterator<Item = TokenTreeWithMetadata<G, I, P, L>>
512 where
513 G: Clone,
514 I: Clone,
515 P: Clone,
516 L: Clone,
517 {
518 iter.into_iter().map(move |tt| (tt, group, ident, punct, literal).into())
519 }
520}