1 #[macro_use]
2 mod macros;
3 
4 use proc_macro2::{Delimiter, Group, Ident, Punct, Spacing, Span, TokenStream, TokenTree};
5 use quote::quote;
6 use std::iter::FromIterator;
7 use syn::Type;
8 
9 #[test]
test_mut_self()10 fn test_mut_self() {
11     syn::parse_str::<Type>("fn(mut self)").unwrap();
12     syn::parse_str::<Type>("fn(mut self: ())").unwrap();
13     syn::parse_str::<Type>("fn(mut self: ...)").unwrap_err();
14     syn::parse_str::<Type>("fn(mut self: mut self)").unwrap_err();
15     syn::parse_str::<Type>("fn(mut self::T)").unwrap_err();
16 }
17 
18 #[test]
test_macro_variable_type()19 fn test_macro_variable_type() {
20     // mimics the token stream corresponding to `$ty<T>`
21     let tokens = TokenStream::from_iter(vec![
22         TokenTree::Group(Group::new(Delimiter::None, quote! { ty })),
23         TokenTree::Punct(Punct::new('<', Spacing::Alone)),
24         TokenTree::Ident(Ident::new("T", Span::call_site())),
25         TokenTree::Punct(Punct::new('>', Spacing::Alone)),
26     ]);
27 
28     snapshot!(tokens as Type, @r###"
29     Type::Path {
30         path: Path {
31             segments: [
32                 PathSegment {
33                     ident: "ty",
34                     arguments: PathArguments::AngleBracketed {
35                         args: [
36                             Type(Type::Path {
37                                 path: Path {
38                                     segments: [
39                                         PathSegment {
40                                             ident: "T",
41                                             arguments: None,
42                                         },
43                                     ],
44                                 },
45                             }),
46                         ],
47                     },
48                 },
49             ],
50         },
51     }
52     "###);
53 
54     // mimics the token stream corresponding to `$ty::<T>`
55     let tokens = TokenStream::from_iter(vec![
56         TokenTree::Group(Group::new(Delimiter::None, quote! { ty })),
57         TokenTree::Punct(Punct::new(':', Spacing::Joint)),
58         TokenTree::Punct(Punct::new(':', Spacing::Alone)),
59         TokenTree::Punct(Punct::new('<', Spacing::Alone)),
60         TokenTree::Ident(Ident::new("T", Span::call_site())),
61         TokenTree::Punct(Punct::new('>', Spacing::Alone)),
62     ]);
63 
64     snapshot!(tokens as Type, @r###"
65     Type::Path {
66         path: Path {
67             segments: [
68                 PathSegment {
69                     ident: "ty",
70                     arguments: PathArguments::AngleBracketed {
71                         colon2_token: Some,
72                         args: [
73                             Type(Type::Path {
74                                 path: Path {
75                                     segments: [
76                                         PathSegment {
77                                             ident: "T",
78                                             arguments: None,
79                                         },
80                                     ],
81                                 },
82                             }),
83                         ],
84                     },
85                 },
86             ],
87         },
88     }
89     "###);
90 }
91 
92 #[test]
test_group_angle_brackets()93 fn test_group_angle_brackets() {
94     // mimics the token stream corresponding to `Option<$ty>`
95     let tokens = TokenStream::from_iter(vec![
96         TokenTree::Ident(Ident::new("Option", Span::call_site())),
97         TokenTree::Punct(Punct::new('<', Spacing::Alone)),
98         TokenTree::Group(Group::new(Delimiter::None, quote! { Vec<u8> })),
99         TokenTree::Punct(Punct::new('>', Spacing::Alone)),
100     ]);
101 
102     snapshot!(tokens as Type, @r###"
103     Type::Path {
104         path: Path {
105             segments: [
106                 PathSegment {
107                     ident: "Option",
108                     arguments: PathArguments::AngleBracketed {
109                         args: [
110                             Type(Type::Group {
111                                 elem: Type::Path {
112                                     path: Path {
113                                         segments: [
114                                             PathSegment {
115                                                 ident: "Vec",
116                                                 arguments: PathArguments::AngleBracketed {
117                                                     args: [
118                                                         Type(Type::Path {
119                                                             path: Path {
120                                                                 segments: [
121                                                                     PathSegment {
122                                                                         ident: "u8",
123                                                                         arguments: None,
124                                                                     },
125                                                                 ],
126                                                             },
127                                                         }),
128                                                     ],
129                                                 },
130                                             },
131                                         ],
132                                     },
133                                 },
134                             }),
135                         ],
136                     },
137                 },
138             ],
139         },
140     }
141     "###);
142 }
143 
144 #[test]
test_group_colons()145 fn test_group_colons() {
146     // mimics the token stream corresponding to `$ty::Item`
147     let tokens = TokenStream::from_iter(vec![
148         TokenTree::Group(Group::new(Delimiter::None, quote! { Vec<u8> })),
149         TokenTree::Punct(Punct::new(':', Spacing::Joint)),
150         TokenTree::Punct(Punct::new(':', Spacing::Alone)),
151         TokenTree::Ident(Ident::new("Item", Span::call_site())),
152     ]);
153 
154     snapshot!(tokens as Type, @r###"
155     Type::Path {
156         path: Path {
157             segments: [
158                 PathSegment {
159                     ident: "Vec",
160                     arguments: PathArguments::AngleBracketed {
161                         args: [
162                             Type(Type::Path {
163                                 path: Path {
164                                     segments: [
165                                         PathSegment {
166                                             ident: "u8",
167                                             arguments: None,
168                                         },
169                                     ],
170                                 },
171                             }),
172                         ],
173                     },
174                 },
175                 PathSegment {
176                     ident: "Item",
177                     arguments: None,
178                 },
179             ],
180         },
181     }
182     "###);
183 
184     let tokens = TokenStream::from_iter(vec![
185         TokenTree::Group(Group::new(Delimiter::None, quote! { [T] })),
186         TokenTree::Punct(Punct::new(':', Spacing::Joint)),
187         TokenTree::Punct(Punct::new(':', Spacing::Alone)),
188         TokenTree::Ident(Ident::new("Element", Span::call_site())),
189     ]);
190 
191     snapshot!(tokens as Type, @r###"
192     Type::Path {
193         qself: Some(QSelf {
194             ty: Type::Slice {
195                 elem: Type::Path {
196                     path: Path {
197                         segments: [
198                             PathSegment {
199                                 ident: "T",
200                                 arguments: None,
201                             },
202                         ],
203                     },
204                 },
205             },
206             position: 0,
207         }),
208         path: Path {
209             leading_colon: Some,
210             segments: [
211                 PathSegment {
212                     ident: "Element",
213                     arguments: None,
214                 },
215             ],
216         },
217     }
218     "###);
219 }
220