prettyplease/
ty.rs

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            #![cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))]
16            Type::Array(ty) => self.type_array(ty),
17            Type::BareFn(ty) => self.type_bare_fn(ty),
18            Type::Group(ty) => self.type_group(ty),
19            Type::ImplTrait(ty) => self.type_impl_trait(ty),
20            Type::Infer(ty) => self.type_infer(ty),
21            Type::Macro(ty) => self.type_macro(ty),
22            Type::Never(ty) => self.type_never(ty),
23            Type::Paren(ty) => self.type_paren(ty),
24            Type::Path(ty) => self.type_path(ty),
25            Type::Ptr(ty) => self.type_ptr(ty),
26            Type::Reference(ty) => self.type_reference(ty),
27            Type::Slice(ty) => self.type_slice(ty),
28            Type::TraitObject(ty) => self.type_trait_object(ty),
29            Type::Tuple(ty) => self.type_tuple(ty),
30            Type::Verbatim(ty) => self.type_verbatim(ty),
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}