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}