prettyplease/
ty.rs

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