core_extensions_proc_macros/macro_utils_shared/
cmp_ts.rs
1#[allow(unused_imports)]
4use crate::{
5 used_proc_macro::{Delimiter, Punct, TokenStream, TokenTree},
6 mmatches,
7};
8
9use core::cmp::PartialEq;
10
11use alloc::{
12 string::{String, ToString},
13 vec::Vec,
14};
15
16
17pub(crate) enum Found {
18 Yes,
19 No,
20}
21
22
23pub(crate) enum ComparableTT {
24 Ident(String),
25 Punct(Punct),
26 Literal(String),
27 Group(ComparableGroup),
28}
29
30
31
32impl ComparableTT {
33 pub(crate) fn new(tt: TokenTree) -> Self {
34 match tt {
35 TokenTree::Ident(ident) => ComparableTT::Ident(ident.to_string()),
36 TokenTree::Punct(x) => ComparableTT::Punct(x),
37 TokenTree::Literal(x) => ComparableTT::Literal(x.to_string()),
38 TokenTree::Group(group) => {
39 let this = ComparableGroup{
40 stream: group.stream().into_iter().map(ComparableTT::new).collect(),
41 delimiter: group.delimiter(),
42 };
43 ComparableTT::Group(this)
44 },
45 }
46 }
47
48 pub(crate) fn many<I>(iter: I) -> Vec<ComparableTT>
49 where
50 I: IntoIterator<Item = TokenTree>
51 {
52 iter.into_iter().map(ComparableTT::new).collect()
53 }
54}
55
56impl PartialEq<ComparableTT> for TokenTree {
57 fn eq(&self, other: &ComparableTT) -> bool {
58 match (self, other) {
59 (TokenTree::Ident(l), ComparableTT::Ident(r)) => l.to_string() == *r,
60 (TokenTree::Punct(l), ComparableTT::Punct(r)) =>
61 l.as_char() == r.as_char() && l.spacing() == r.spacing() ,
62 (TokenTree::Literal(l), ComparableTT::Literal(r)) => l.to_string() == *r,
63 (TokenTree::Group(l), ComparableTT::Group(r)) => {
64 l.stream().into_iter().eq(r.stream.iter()) &&
65 l.delimiter() == r.delimiter
66 }
67 _ => false,
68 }
69 }
70}
71
72impl PartialEq<&ComparableTT> for TokenTree {
73 fn eq(&self, other: &&ComparableTT) -> bool {
74 *self == **other
75 }
76}
77
78
79pub(crate) struct ComparableGroup {
80 pub(crate) stream: Vec<ComparableTT>,
81 pub(crate) delimiter: Delimiter,
82}
83
84
85pub(crate) fn skip_until_match<I>(mut iter: I, s_tokens: &[ComparableTT]) -> (TokenStream, Found)
86where
87 I: Iterator<Item = TokenTree>
88{
89 let mut cmp_iter = s_tokens.iter();
90
91 let mut out = Vec::new();
92
93 while let Some(next) = cmp_iter.next() {
94 match iter.next() {
95 Some(tt) => {
96 if tt != *next {
97 cmp_iter = s_tokens.iter();
98 if tt == s_tokens[0] {
99 cmp_iter.next();
100 }
101 }
102 out.push(tt);
103 }
104 None => return (out.into_iter().collect(), Found::No),
105 }
106 }
107
108 let found = if s_tokens.is_empty() { Found::No } else { Found::Yes };
109
110 out.truncate(out.len() - s_tokens.len());
111 (out.into_iter().collect(), found)
112}
113
114
115
116
117
118
119
120
121
122