1use crate::algorithm::Printer;
2use crate::iter::IterDelimited;
3use crate::path::PathKind;
4use crate::INDENT;
5use proc_macro2::TokenStream;
6use syn::{
7 Abi, BareFnArg, BareVariadic, ReturnType, Type, TypeArray, TypeBareFn, TypeGroup,
8 TypeImplTrait, TypeInfer, TypeMacro, TypeNever, TypeParen, TypePath, TypePtr, TypeReference,
9 TypeSlice, TypeTraitObject, TypeTuple,
10};
11
12impl Printer {
13 pub fn ty(&mut self, ty: &Type) {
14 match ty {
15 Type::Array(ty) => self.type_array(ty),
16 Type::BareFn(ty) => self.type_bare_fn(ty),
17 Type::Group(ty) => self.type_group(ty),
18 Type::ImplTrait(ty) => self.type_impl_trait(ty),
19 Type::Infer(ty) => self.type_infer(ty),
20 Type::Macro(ty) => self.type_macro(ty),
21 Type::Never(ty) => self.type_never(ty),
22 Type::Paren(ty) => self.type_paren(ty),
23 Type::Path(ty) => self.type_path(ty),
24 Type::Ptr(ty) => self.type_ptr(ty),
25 Type::Reference(ty) => self.type_reference(ty),
26 Type::Slice(ty) => self.type_slice(ty),
27 Type::TraitObject(ty) => self.type_trait_object(ty),
28 Type::Tuple(ty) => self.type_tuple(ty),
29 Type::Verbatim(ty) => self.type_verbatim(ty),
30 #[cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))]
31 _ => unimplemented!("unknown Type"),
32 }
33 }
34
35 fn type_array(&mut self, ty: &TypeArray) {
36 self.word("[");
37 self.ty(&ty.elem);
38 self.word("; ");
39 self.expr(&ty.len);
40 self.word("]");
41 }
42
43 fn type_bare_fn(&mut self, ty: &TypeBareFn) {
44 if let Some(bound_lifetimes) = &ty.lifetimes {
45 self.bound_lifetimes(bound_lifetimes);
46 }
47 if ty.unsafety.is_some() {
48 self.word("unsafe ");
49 }
50 if let Some(abi) = &ty.abi {
51 self.abi(abi);
52 }
53 self.word("fn(");
54 self.cbox(INDENT);
55 self.zerobreak();
56 for bare_fn_arg in ty.inputs.iter().delimited() {
57 self.bare_fn_arg(&bare_fn_arg);
58 self.trailing_comma(bare_fn_arg.is_last && ty.variadic.is_none());
59 }
60 if let Some(variadic) = &ty.variadic {
61 self.bare_variadic(variadic);
62 self.zerobreak();
63 }
64 self.offset(-INDENT);
65 self.end();
66 self.word(")");
67 self.return_type(&ty.output);
68 }
69
70 fn type_group(&mut self, ty: &TypeGroup) {
71 self.ty(&ty.elem);
72 }
73
74 fn type_impl_trait(&mut self, ty: &TypeImplTrait) {
75 self.word("impl ");
76 for type_param_bound in ty.bounds.iter().delimited() {
77 if !type_param_bound.is_first {
78 self.word(" + ");
79 }
80 self.type_param_bound(&type_param_bound);
81 }
82 }
83
84 fn type_infer(&mut self, ty: &TypeInfer) {
85 let _ = ty;
86 self.word("_");
87 }
88
89 fn type_macro(&mut self, ty: &TypeMacro) {
90 let semicolon = false;
91 self.mac(&ty.mac, None, semicolon);
92 }
93
94 fn type_never(&mut self, ty: &TypeNever) {
95 let _ = ty;
96 self.word("!");
97 }
98
99 fn type_paren(&mut self, ty: &TypeParen) {
100 self.word("(");
101 self.ty(&ty.elem);
102 self.word(")");
103 }
104
105 fn type_path(&mut self, ty: &TypePath) {
106 self.qpath(&ty.qself, &ty.path, PathKind::Type);
107 }
108
109 fn type_ptr(&mut self, ty: &TypePtr) {
110 self.word("*");
111 if ty.mutability.is_some() {
112 self.word("mut ");
113 } else {
114 self.word("const ");
115 }
116 self.ty(&ty.elem);
117 }
118
119 fn type_reference(&mut self, ty: &TypeReference) {
120 self.word("&");
121 if let Some(lifetime) = &ty.lifetime {
122 self.lifetime(lifetime);
123 self.nbsp();
124 }
125 if ty.mutability.is_some() {
126 self.word("mut ");
127 }
128 self.ty(&ty.elem);
129 }
130
131 fn type_slice(&mut self, ty: &TypeSlice) {
132 self.word("[");
133 self.ty(&ty.elem);
134 self.word("]");
135 }
136
137 fn type_trait_object(&mut self, ty: &TypeTraitObject) {
138 self.word("dyn ");
139 for type_param_bound in ty.bounds.iter().delimited() {
140 if !type_param_bound.is_first {
141 self.word(" + ");
142 }
143 self.type_param_bound(&type_param_bound);
144 }
145 }
146
147 fn type_tuple(&mut self, ty: &TypeTuple) {
148 self.word("(");
149 self.cbox(INDENT);
150 self.zerobreak();
151 for elem in ty.elems.iter().delimited() {
152 self.ty(&elem);
153 if ty.elems.len() == 1 {
154 self.word(",");
155 self.zerobreak();
156 } else {
157 self.trailing_comma(elem.is_last);
158 }
159 }
160 self.offset(-INDENT);
161 self.end();
162 self.word(")");
163 }
164
165 #[cfg(not(feature = "verbatim"))]
166 fn type_verbatim(&mut self, ty: &TokenStream) {
167 unimplemented!("Type::Verbatim `{}`", ty);
168 }
169
170 #[cfg(feature = "verbatim")]
171 fn type_verbatim(&mut self, tokens: &TokenStream) {
172 use syn::parse::{Parse, ParseStream, Result};
173 use syn::punctuated::Punctuated;
174 use syn::{token, FieldsNamed, Token, TypeParamBound};
175
176 enum TypeVerbatim {
177 Ellipsis,
178 AnonStruct(AnonStruct),
179 AnonUnion(AnonUnion),
180 DynStar(DynStar),
181 MutSelf(MutSelf),
182 NotType(NotType),
183 }
184
185 struct AnonStruct {
186 fields: FieldsNamed,
187 }
188
189 struct AnonUnion {
190 fields: FieldsNamed,
191 }
192
193 struct DynStar {
194 bounds: Punctuated<TypeParamBound, Token![+]>,
195 }
196
197 struct MutSelf {
198 ty: Option<Type>,
199 }
200
201 struct NotType {
202 inner: Type,
203 }
204
205 impl Parse for TypeVerbatim {
206 fn parse(input: ParseStream) -> Result<Self> {
207 let lookahead = input.lookahead1();
208 if lookahead.peek(Token![struct]) {
209 input.parse::<Token![struct]>()?;
210 let fields: FieldsNamed = input.parse()?;
211 Ok(TypeVerbatim::AnonStruct(AnonStruct { fields }))
212 } else if lookahead.peek(Token![union]) && input.peek2(token::Brace) {
213 input.parse::<Token![union]>()?;
214 let fields: FieldsNamed = input.parse()?;
215 Ok(TypeVerbatim::AnonUnion(AnonUnion { fields }))
216 } else if lookahead.peek(Token![dyn]) {
217 input.parse::<Token![dyn]>()?;
218 input.parse::<Token![*]>()?;
219 let bounds = input.parse_terminated(TypeParamBound::parse, Token![+])?;
220 Ok(TypeVerbatim::DynStar(DynStar { bounds }))
221 } else if lookahead.peek(Token![mut]) {
222 input.parse::<Token![mut]>()?;
223 input.parse::<Token![self]>()?;
224 let ty = if input.is_empty() {
225 None
226 } else {
227 input.parse::<Token![:]>()?;
228 let ty: Type = input.parse()?;
229 Some(ty)
230 };
231 Ok(TypeVerbatim::MutSelf(MutSelf { ty }))
232 } else if lookahead.peek(Token![!]) {
233 input.parse::<Token![!]>()?;
234 let inner: Type = input.parse()?;
235 Ok(TypeVerbatim::NotType(NotType { inner }))
236 } else if lookahead.peek(Token![...]) {
237 input.parse::<Token![...]>()?;
238 Ok(TypeVerbatim::Ellipsis)
239 } else {
240 Err(lookahead.error())
241 }
242 }
243 }
244
245 let ty: TypeVerbatim = match syn::parse2(tokens.clone()) {
246 Ok(ty) => ty,
247 Err(_) => unimplemented!("Type::Verbatim `{}`", tokens),
248 };
249
250 match ty {
251 TypeVerbatim::Ellipsis => {
252 self.word("...");
253 }
254 TypeVerbatim::AnonStruct(ty) => {
255 self.cbox(INDENT);
256 self.word("struct {");
257 self.hardbreak_if_nonempty();
258 for field in &ty.fields.named {
259 self.field(field);
260 self.word(",");
261 self.hardbreak();
262 }
263 self.offset(-INDENT);
264 self.end();
265 self.word("}");
266 }
267 TypeVerbatim::AnonUnion(ty) => {
268 self.cbox(INDENT);
269 self.word("union {");
270 self.hardbreak_if_nonempty();
271 for field in &ty.fields.named {
272 self.field(field);
273 self.word(",");
274 self.hardbreak();
275 }
276 self.offset(-INDENT);
277 self.end();
278 self.word("}");
279 }
280 TypeVerbatim::DynStar(ty) => {
281 self.word("dyn* ");
282 for type_param_bound in ty.bounds.iter().delimited() {
283 if !type_param_bound.is_first {
284 self.word(" + ");
285 }
286 self.type_param_bound(&type_param_bound);
287 }
288 }
289 TypeVerbatim::MutSelf(bare_fn_arg) => {
290 self.word("mut self");
291 if let Some(ty) = &bare_fn_arg.ty {
292 self.word(": ");
293 self.ty(ty);
294 }
295 }
296 TypeVerbatim::NotType(ty) => {
297 self.word("!");
298 self.ty(&ty.inner);
299 }
300 }
301 }
302
303 pub fn return_type(&mut self, ty: &ReturnType) {
304 match ty {
305 ReturnType::Default => {}
306 ReturnType::Type(_arrow, ty) => {
307 self.word(" -> ");
308 self.ty(ty);
309 }
310 }
311 }
312
313 fn bare_fn_arg(&mut self, bare_fn_arg: &BareFnArg) {
314 self.outer_attrs(&bare_fn_arg.attrs);
315 if let Some((name, _colon)) = &bare_fn_arg.name {
316 self.ident(name);
317 self.word(": ");
318 }
319 self.ty(&bare_fn_arg.ty);
320 }
321
322 fn bare_variadic(&mut self, variadic: &BareVariadic) {
323 self.outer_attrs(&variadic.attrs);
324 if let Some((name, _colon)) = &variadic.name {
325 self.ident(name);
326 self.word(": ");
327 }
328 self.word("...");
329 }
330
331 pub fn abi(&mut self, abi: &Abi) {
332 self.word("extern ");
333 if let Some(name) = &abi.name {
334 self.lit_str(name);
335 self.nbsp();
336 }
337 }
338}
339