1use crate::algorithm::Printer;
2use crate::iter::IterDelimited;
3use crate::path::PathKind;
4use crate::INDENT;
5use proc_macro2::TokenStream;
6use syn::{
7 Fields, FnArg, ForeignItem, ForeignItemFn, ForeignItemMacro, ForeignItemStatic,
8 ForeignItemType, ImplItem, ImplItemConst, ImplItemFn, ImplItemMacro, ImplItemType, Item,
9 ItemConst, ItemEnum, ItemExternCrate, ItemFn, ItemForeignMod, ItemImpl, ItemMacro, ItemMod,
10 ItemStatic, ItemStruct, ItemTrait, ItemTraitAlias, ItemType, ItemUnion, ItemUse, Receiver,
11 Signature, StaticMutability, TraitItem, TraitItemConst, TraitItemFn, TraitItemMacro,
12 TraitItemType, Type, UseGlob, UseGroup, UseName, UsePath, UseRename, UseTree, Variadic,
13};
14
15impl Printer {
16 pub fn item(&mut self, item: &Item) {
17 match item {
18 #![cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))]
19 Item::Const(item) => self.item_const(item),
20 Item::Enum(item) => self.item_enum(item),
21 Item::ExternCrate(item) => self.item_extern_crate(item),
22 Item::Fn(item) => self.item_fn(item),
23 Item::ForeignMod(item) => self.item_foreign_mod(item),
24 Item::Impl(item) => self.item_impl(item),
25 Item::Macro(item) => self.item_macro(item),
26 Item::Mod(item) => self.item_mod(item),
27 Item::Static(item) => self.item_static(item),
28 Item::Struct(item) => self.item_struct(item),
29 Item::Trait(item) => self.item_trait(item),
30 Item::TraitAlias(item) => self.item_trait_alias(item),
31 Item::Type(item) => self.item_type(item),
32 Item::Union(item) => self.item_union(item),
33 Item::Use(item) => self.item_use(item),
34 Item::Verbatim(item) => self.item_verbatim(item),
35 _ => unimplemented!("unknown Item"),
36 }
37 }
38
39 fn item_const(&mut self, item: &ItemConst) {
40 self.outer_attrs(&item.attrs);
41 self.cbox(0);
42 self.visibility(&item.vis);
43 self.word("const ");
44 self.ident(&item.ident);
45 self.generics(&item.generics);
46 self.word(": ");
47 self.ty(&item.ty);
48 self.word(" = ");
49 self.neverbreak();
50 self.expr(&item.expr);
51 self.word(";");
52 self.end();
53 self.hardbreak();
54 }
55
56 fn item_enum(&mut self, item: &ItemEnum) {
57 self.outer_attrs(&item.attrs);
58 self.cbox(INDENT);
59 self.visibility(&item.vis);
60 self.word("enum ");
61 self.ident(&item.ident);
62 self.generics(&item.generics);
63 self.where_clause_for_body(&item.generics.where_clause);
64 self.word("{");
65 self.hardbreak_if_nonempty();
66 for variant in &item.variants {
67 self.variant(variant);
68 self.word(",");
69 self.hardbreak();
70 }
71 self.offset(-INDENT);
72 self.end();
73 self.word("}");
74 self.hardbreak();
75 }
76
77 fn item_extern_crate(&mut self, item: &ItemExternCrate) {
78 self.outer_attrs(&item.attrs);
79 self.visibility(&item.vis);
80 self.word("extern crate ");
81 self.ident(&item.ident);
82 if let Some((_as_token, rename)) = &item.rename {
83 self.word(" as ");
84 self.ident(rename);
85 }
86 self.word(";");
87 self.hardbreak();
88 }
89
90 fn item_fn(&mut self, item: &ItemFn) {
91 self.outer_attrs(&item.attrs);
92 self.cbox(INDENT);
93 self.visibility(&item.vis);
94 self.signature(
95 &item.sig,
96 #[cfg(feature = "verbatim")]
97 &verbatim::Safety::Disallowed,
98 );
99 self.where_clause_for_body(&item.sig.generics.where_clause);
100 self.word("{");
101 self.hardbreak_if_nonempty();
102 self.inner_attrs(&item.attrs);
103 for stmt in &item.block.stmts {
104 self.stmt(stmt);
105 }
106 self.offset(-INDENT);
107 self.end();
108 self.word("}");
109 self.hardbreak();
110 }
111
112 fn item_foreign_mod(&mut self, item: &ItemForeignMod) {
113 self.outer_attrs(&item.attrs);
114 self.cbox(INDENT);
115 if item.unsafety.is_some() {
116 self.word("unsafe ");
117 }
118 self.abi(&item.abi);
119 self.word("{");
120 self.hardbreak_if_nonempty();
121 self.inner_attrs(&item.attrs);
122 for foreign_item in &item.items {
123 self.foreign_item(foreign_item);
124 }
125 self.offset(-INDENT);
126 self.end();
127 self.word("}");
128 self.hardbreak();
129 }
130
131 fn item_impl(&mut self, item: &ItemImpl) {
132 self.outer_attrs(&item.attrs);
133 self.cbox(INDENT);
134 self.ibox(-INDENT);
135 self.cbox(INDENT);
136 if item.defaultness.is_some() {
137 self.word("default ");
138 }
139 if item.unsafety.is_some() {
140 self.word("unsafe ");
141 }
142 self.word("impl");
143 self.generics(&item.generics);
144 self.end();
145 self.nbsp();
146 if let Some((negative_polarity, path, _for_token)) = &item.trait_ {
147 if negative_polarity.is_some() {
148 self.word("!");
149 }
150 self.path(path, PathKind::Type);
151 self.space();
152 self.word("for ");
153 }
154 self.ty(&item.self_ty);
155 self.end();
156 self.where_clause_for_body(&item.generics.where_clause);
157 self.word("{");
158 self.hardbreak_if_nonempty();
159 self.inner_attrs(&item.attrs);
160 for impl_item in &item.items {
161 self.impl_item(impl_item);
162 }
163 self.offset(-INDENT);
164 self.end();
165 self.word("}");
166 self.hardbreak();
167 }
168
169 fn item_macro(&mut self, item: &ItemMacro) {
170 self.outer_attrs(&item.attrs);
171 let semicolon = true;
172 self.mac(&item.mac, item.ident.as_ref(), semicolon);
173 self.hardbreak();
174 }
175
176 fn item_mod(&mut self, item: &ItemMod) {
177 self.outer_attrs(&item.attrs);
178 self.cbox(INDENT);
179 self.visibility(&item.vis);
180 if item.unsafety.is_some() {
181 self.word("unsafe ");
182 }
183 self.word("mod ");
184 self.ident(&item.ident);
185 if let Some((_brace, items)) = &item.content {
186 self.word(" {");
187 self.hardbreak_if_nonempty();
188 self.inner_attrs(&item.attrs);
189 for item in items {
190 self.item(item);
191 }
192 self.offset(-INDENT);
193 self.end();
194 self.word("}");
195 } else {
196 self.word(";");
197 self.end();
198 }
199 self.hardbreak();
200 }
201
202 fn item_static(&mut self, item: &ItemStatic) {
203 self.outer_attrs(&item.attrs);
204 self.cbox(0);
205 self.visibility(&item.vis);
206 self.word("static ");
207 self.static_mutability(&item.mutability);
208 self.ident(&item.ident);
209 self.word(": ");
210 self.ty(&item.ty);
211 self.word(" = ");
212 self.neverbreak();
213 self.expr(&item.expr);
214 self.word(";");
215 self.end();
216 self.hardbreak();
217 }
218
219 fn item_struct(&mut self, item: &ItemStruct) {
220 self.outer_attrs(&item.attrs);
221 self.cbox(INDENT);
222 self.visibility(&item.vis);
223 self.word("struct ");
224 self.ident(&item.ident);
225 self.generics(&item.generics);
226 match &item.fields {
227 Fields::Named(fields) => {
228 self.where_clause_for_body(&item.generics.where_clause);
229 self.word("{");
230 self.hardbreak_if_nonempty();
231 for field in &fields.named {
232 self.field(field);
233 self.word(",");
234 self.hardbreak();
235 }
236 self.offset(-INDENT);
237 self.end();
238 self.word("}");
239 }
240 Fields::Unnamed(fields) => {
241 self.fields_unnamed(fields);
242 self.where_clause_semi(&item.generics.where_clause);
243 self.end();
244 }
245 Fields::Unit => {
246 self.where_clause_semi(&item.generics.where_clause);
247 self.end();
248 }
249 }
250 self.hardbreak();
251 }
252
253 fn item_trait(&mut self, item: &ItemTrait) {
254 self.outer_attrs(&item.attrs);
255 self.cbox(INDENT);
256 self.visibility(&item.vis);
257 if item.unsafety.is_some() {
258 self.word("unsafe ");
259 }
260 if item.auto_token.is_some() {
261 self.word("auto ");
262 }
263 self.word("trait ");
264 self.ident(&item.ident);
265 self.generics(&item.generics);
266 for supertrait in item.supertraits.iter().delimited() {
267 if supertrait.is_first {
268 self.word(": ");
269 } else {
270 self.word(" + ");
271 }
272 self.type_param_bound(&supertrait);
273 }
274 self.where_clause_for_body(&item.generics.where_clause);
275 self.word("{");
276 self.hardbreak_if_nonempty();
277 self.inner_attrs(&item.attrs);
278 for trait_item in &item.items {
279 self.trait_item(trait_item);
280 }
281 self.offset(-INDENT);
282 self.end();
283 self.word("}");
284 self.hardbreak();
285 }
286
287 fn item_trait_alias(&mut self, item: &ItemTraitAlias) {
288 self.outer_attrs(&item.attrs);
289 self.cbox(INDENT);
290 self.visibility(&item.vis);
291 self.word("trait ");
292 self.ident(&item.ident);
293 self.generics(&item.generics);
294 self.word(" = ");
295 self.neverbreak();
296 for bound in item.bounds.iter().delimited() {
297 if !bound.is_first {
298 self.space();
299 self.word("+ ");
300 }
301 self.type_param_bound(&bound);
302 }
303 self.where_clause_semi(&item.generics.where_clause);
304 self.end();
305 self.hardbreak();
306 }
307
308 fn item_type(&mut self, item: &ItemType) {
309 self.outer_attrs(&item.attrs);
310 self.cbox(INDENT);
311 self.visibility(&item.vis);
312 self.word("type ");
313 self.ident(&item.ident);
314 self.generics(&item.generics);
315 self.where_clause_oneline(&item.generics.where_clause);
316 self.word("= ");
317 self.neverbreak();
318 self.ibox(-INDENT);
319 self.ty(&item.ty);
320 self.end();
321 self.word(";");
322 self.end();
323 self.hardbreak();
324 }
325
326 fn item_union(&mut self, item: &ItemUnion) {
327 self.outer_attrs(&item.attrs);
328 self.cbox(INDENT);
329 self.visibility(&item.vis);
330 self.word("union ");
331 self.ident(&item.ident);
332 self.generics(&item.generics);
333 self.where_clause_for_body(&item.generics.where_clause);
334 self.word("{");
335 self.hardbreak_if_nonempty();
336 for field in &item.fields.named {
337 self.field(field);
338 self.word(",");
339 self.hardbreak();
340 }
341 self.offset(-INDENT);
342 self.end();
343 self.word("}");
344 self.hardbreak();
345 }
346
347 fn item_use(&mut self, item: &ItemUse) {
348 self.outer_attrs(&item.attrs);
349 self.visibility(&item.vis);
350 self.word("use ");
351 if item.leading_colon.is_some() {
352 self.word("::");
353 }
354 self.use_tree(&item.tree);
355 self.word(";");
356 self.hardbreak();
357 }
358
359 #[cfg(not(feature = "verbatim"))]
360 fn item_verbatim(&mut self, item: &TokenStream) {
361 if !item.is_empty() {
362 unimplemented!("Item::Verbatim `{}`", item);
363 }
364 self.hardbreak();
365 }
366
367 #[cfg(feature = "verbatim")]
368 fn item_verbatim(&mut self, tokens: &TokenStream) {
369 use syn::parse::{Parse, ParseStream, Result};
370 use syn::punctuated::Punctuated;
371 use syn::{
372 braced, parenthesized, token, Attribute, Generics, Ident, Lifetime, Token, Visibility,
373 };
374 use verbatim::{
375 FlexibleItemConst, FlexibleItemFn, FlexibleItemStatic, FlexibleItemType,
376 WhereClauseLocation,
377 };
378
379 enum ItemVerbatim {
380 Empty,
381 Ellipsis,
382 ConstFlexible(FlexibleItemConst),
383 FnFlexible(FlexibleItemFn),
384 ImplFlexible(ImplFlexible),
385 Macro2(Macro2),
386 StaticFlexible(FlexibleItemStatic),
387 TypeFlexible(FlexibleItemType),
388 UseBrace(UseBrace),
389 }
390
391 struct ImplFlexible {
392 attrs: Vec<Attribute>,
393 vis: Visibility,
394 defaultness: bool,
395 unsafety: bool,
396 generics: Generics,
397 constness: ImplConstness,
398 negative_impl: bool,
399 trait_: Option<Type>,
400 self_ty: Type,
401 items: Vec<ImplItem>,
402 }
403
404 enum ImplConstness {
405 None,
406 MaybeConst,
407 Const,
408 }
409
410 struct Macro2 {
411 attrs: Vec<Attribute>,
412 vis: Visibility,
413 ident: Ident,
414 args: Option<TokenStream>,
415 body: TokenStream,
416 }
417
418 struct UseBrace {
419 attrs: Vec<Attribute>,
420 vis: Visibility,
421 trees: Punctuated<RootUseTree, Token![,]>,
422 }
423
424 struct RootUseTree {
425 leading_colon: Option<Token![::]>,
426 inner: UseTree,
427 }
428
429 impl Parse for ImplConstness {
430 fn parse(input: ParseStream) -> Result<Self> {
431 if input.parse::<Option<Token![?]>>()?.is_some() {
432 input.parse::<Token![const]>()?;
433 Ok(ImplConstness::MaybeConst)
434 } else if input.parse::<Option<Token![const]>>()?.is_some() {
435 Ok(ImplConstness::Const)
436 } else {
437 Ok(ImplConstness::None)
438 }
439 }
440 }
441
442 impl Parse for RootUseTree {
443 fn parse(input: ParseStream) -> Result<Self> {
444 Ok(RootUseTree {
445 leading_colon: input.parse()?,
446 inner: input.parse()?,
447 })
448 }
449 }
450
451 impl Parse for ItemVerbatim {
452 fn parse(input: ParseStream) -> Result<Self> {
453 if input.is_empty() {
454 return Ok(ItemVerbatim::Empty);
455 } else if input.peek(Token![...]) {
456 input.parse::<Token![...]>()?;
457 return Ok(ItemVerbatim::Ellipsis);
458 }
459
460 let mut attrs = input.call(Attribute::parse_outer)?;
461 let vis: Visibility = input.parse()?;
462
463 let lookahead = input.lookahead1();
464 if lookahead.peek(Token![const]) && (input.peek2(Ident) || input.peek2(Token![_])) {
465 let defaultness = false;
466 let flexible_item = FlexibleItemConst::parse(attrs, vis, defaultness, input)?;
467 Ok(ItemVerbatim::ConstFlexible(flexible_item))
468 } else if input.peek(Token![const])
469 || lookahead.peek(Token![async])
470 || lookahead.peek(Token![unsafe]) && !input.peek2(Token![impl])
471 || lookahead.peek(Token![extern])
472 || lookahead.peek(Token![fn])
473 {
474 let defaultness = false;
475 let flexible_item = FlexibleItemFn::parse(attrs, vis, defaultness, input)?;
476 Ok(ItemVerbatim::FnFlexible(flexible_item))
477 } else if lookahead.peek(Token![default])
478 || input.peek(Token![unsafe])
479 || lookahead.peek(Token![impl])
480 {
481 let defaultness = input.parse::<Option<Token![default]>>()?.is_some();
482 let unsafety = input.parse::<Option<Token![unsafe]>>()?.is_some();
483 input.parse::<Token![impl]>()?;
484 let has_generics = input.peek(Token![<])
485 && (input.peek2(Token![>])
486 || input.peek2(Token![#])
487 || (input.peek2(Ident) || input.peek2(Lifetime))
488 && (input.peek3(Token![:])
489 || input.peek3(Token![,])
490 || input.peek3(Token![>])
491 || input.peek3(Token![=]))
492 || input.peek2(Token![const]));
493 let mut generics: Generics = if has_generics {
494 input.parse()?
495 } else {
496 Generics::default()
497 };
498 let constness: ImplConstness = input.parse()?;
499 let negative_impl =
500 !input.peek2(token::Brace) && input.parse::<Option<Token![!]>>()?.is_some();
501 let first_ty: Type = input.parse()?;
502 let (trait_, self_ty) = if input.parse::<Option<Token![for]>>()?.is_some() {
503 (Some(first_ty), input.parse()?)
504 } else {
505 (None, first_ty)
506 };
507 generics.where_clause = input.parse()?;
508 let content;
509 braced!(content in input);
510 let inner_attrs = content.call(Attribute::parse_inner)?;
511 attrs.extend(inner_attrs);
512 let mut items = Vec::new();
513 while !content.is_empty() {
514 items.push(content.parse()?);
515 }
516 Ok(ItemVerbatim::ImplFlexible(ImplFlexible {
517 attrs,
518 vis,
519 defaultness,
520 unsafety,
521 generics,
522 constness,
523 negative_impl,
524 trait_,
525 self_ty,
526 items,
527 }))
528 } else if lookahead.peek(Token![macro]) {
529 input.parse::<Token![macro]>()?;
530 let ident: Ident = input.parse()?;
531 let args = if input.peek(token::Paren) {
532 let paren_content;
533 parenthesized!(paren_content in input);
534 Some(paren_content.parse::<TokenStream>()?)
535 } else {
536 None
537 };
538 let brace_content;
539 braced!(brace_content in input);
540 let body: TokenStream = brace_content.parse()?;
541 Ok(ItemVerbatim::Macro2(Macro2 {
542 attrs,
543 vis,
544 ident,
545 args,
546 body,
547 }))
548 } else if lookahead.peek(Token![static]) {
549 let flexible_item = FlexibleItemStatic::parse(attrs, vis, input)?;
550 Ok(ItemVerbatim::StaticFlexible(flexible_item))
551 } else if lookahead.peek(Token![type]) {
552 let defaultness = false;
553 let flexible_item = FlexibleItemType::parse(
554 attrs,
555 vis,
556 defaultness,
557 input,
558 WhereClauseLocation::BeforeEq,
559 )?;
560 Ok(ItemVerbatim::TypeFlexible(flexible_item))
561 } else if lookahead.peek(Token![use]) {
562 input.parse::<Token![use]>()?;
563 let content;
564 braced!(content in input);
565 let trees = content.parse_terminated(RootUseTree::parse, Token![,])?;
566 input.parse::<Token![;]>()?;
567 Ok(ItemVerbatim::UseBrace(UseBrace { attrs, vis, trees }))
568 } else {
569 Err(lookahead.error())
570 }
571 }
572 }
573
574 let item: ItemVerbatim = match syn::parse2(tokens.clone()) {
575 Ok(item) => item,
576 Err(_) => unimplemented!("Item::Verbatim `{}`", tokens),
577 };
578
579 match item {
580 ItemVerbatim::Empty => {
581 self.hardbreak();
582 }
583 ItemVerbatim::Ellipsis => {
584 self.word("...");
585 self.hardbreak();
586 }
587 ItemVerbatim::ConstFlexible(item) => {
588 self.flexible_item_const(&item);
589 }
590 ItemVerbatim::FnFlexible(item) => {
591 self.flexible_item_fn(&item);
592 }
593 ItemVerbatim::ImplFlexible(item) => {
594 self.outer_attrs(&item.attrs);
595 self.cbox(INDENT);
596 self.ibox(-INDENT);
597 self.cbox(INDENT);
598 self.visibility(&item.vis);
599 if item.defaultness {
600 self.word("default ");
601 }
602 if item.unsafety {
603 self.word("unsafe ");
604 }
605 self.word("impl");
606 self.generics(&item.generics);
607 self.end();
608 self.nbsp();
609 match item.constness {
610 ImplConstness::None => {}
611 ImplConstness::MaybeConst => self.word("?const "),
612 ImplConstness::Const => self.word("const "),
613 }
614 if item.negative_impl {
615 self.word("!");
616 }
617 if let Some(trait_) = &item.trait_ {
618 self.ty(trait_);
619 self.space();
620 self.word("for ");
621 }
622 self.ty(&item.self_ty);
623 self.end();
624 self.where_clause_for_body(&item.generics.where_clause);
625 self.word("{");
626 self.hardbreak_if_nonempty();
627 self.inner_attrs(&item.attrs);
628 for impl_item in &item.items {
629 self.impl_item(impl_item);
630 }
631 self.offset(-INDENT);
632 self.end();
633 self.word("}");
634 self.hardbreak();
635 }
636 ItemVerbatim::Macro2(item) => {
637 self.outer_attrs(&item.attrs);
638 self.visibility(&item.vis);
639 self.word("macro ");
640 self.ident(&item.ident);
641 if let Some(args) = &item.args {
642 self.word("(");
643 self.cbox(INDENT);
644 self.zerobreak();
645 self.ibox(0);
646 self.macro_rules_tokens(args.clone(), true);
647 self.end();
648 self.zerobreak();
649 self.offset(-INDENT);
650 self.end();
651 self.word(")");
652 }
653 self.word(" {");
654 if !item.body.is_empty() {
655 self.neverbreak();
656 self.cbox(INDENT);
657 self.hardbreak();
658 self.ibox(0);
659 self.macro_rules_tokens(item.body.clone(), false);
660 self.end();
661 self.hardbreak();
662 self.offset(-INDENT);
663 self.end();
664 }
665 self.word("}");
666 self.hardbreak();
667 }
668 ItemVerbatim::StaticFlexible(item) => {
669 self.flexible_item_static(&item);
670 }
671 ItemVerbatim::TypeFlexible(item) => {
672 self.flexible_item_type(&item);
673 }
674 ItemVerbatim::UseBrace(item) => {
675 self.outer_attrs(&item.attrs);
676 self.visibility(&item.vis);
677 self.word("use ");
678 if item.trees.len() == 1 {
679 self.word("::");
680 self.use_tree(&item.trees[0].inner);
681 } else {
682 self.cbox(INDENT);
683 self.word("{");
684 self.zerobreak();
685 self.ibox(0);
686 for use_tree in item.trees.iter().delimited() {
687 if use_tree.leading_colon.is_some() {
688 self.word("::");
689 }
690 self.use_tree(&use_tree.inner);
691 if !use_tree.is_last {
692 self.word(",");
693 let mut use_tree = &use_tree.inner;
694 while let UseTree::Path(use_path) = use_tree {
695 use_tree = &use_path.tree;
696 }
697 if let UseTree::Group(_) = use_tree {
698 self.hardbreak();
699 } else {
700 self.space();
701 }
702 }
703 }
704 self.end();
705 self.trailing_comma(true);
706 self.offset(-INDENT);
707 self.word("}");
708 self.end();
709 }
710 self.word(";");
711 self.hardbreak();
712 }
713 }
714 }
715
716 fn use_tree(&mut self, use_tree: &UseTree) {
717 match use_tree {
718 UseTree::Path(use_path) => self.use_path(use_path),
719 UseTree::Name(use_name) => self.use_name(use_name),
720 UseTree::Rename(use_rename) => self.use_rename(use_rename),
721 UseTree::Glob(use_glob) => self.use_glob(use_glob),
722 UseTree::Group(use_group) => self.use_group(use_group),
723 }
724 }
725
726 fn use_path(&mut self, use_path: &UsePath) {
727 self.ident(&use_path.ident);
728 self.word("::");
729 self.use_tree(&use_path.tree);
730 }
731
732 fn use_name(&mut self, use_name: &UseName) {
733 self.ident(&use_name.ident);
734 }
735
736 fn use_rename(&mut self, use_rename: &UseRename) {
737 self.ident(&use_rename.ident);
738 self.word(" as ");
739 self.ident(&use_rename.rename);
740 }
741
742 fn use_glob(&mut self, use_glob: &UseGlob) {
743 let _ = use_glob;
744 self.word("*");
745 }
746
747 fn use_group(&mut self, use_group: &UseGroup) {
748 if use_group.items.is_empty() {
749 self.word("{}");
750 } else if use_group.items.len() == 1
751 && match &use_group.items[0] {
752 UseTree::Rename(use_rename) => use_rename.ident != "self",
753 _ => true,
754 }
755 {
756 self.use_tree(&use_group.items[0]);
757 } else {
758 self.cbox(INDENT);
759 self.word("{");
760 self.zerobreak();
761 self.ibox(0);
762 for use_tree in use_group.items.iter().delimited() {
763 self.use_tree(&use_tree);
764 if !use_tree.is_last {
765 self.word(",");
766 let mut use_tree = *use_tree;
767 while let UseTree::Path(use_path) = use_tree {
768 use_tree = &use_path.tree;
769 }
770 if let UseTree::Group(_) = use_tree {
771 self.hardbreak();
772 } else {
773 self.space();
774 }
775 }
776 }
777 self.end();
778 self.trailing_comma(true);
779 self.offset(-INDENT);
780 self.word("}");
781 self.end();
782 }
783 }
784
785 fn foreign_item(&mut self, foreign_item: &ForeignItem) {
786 match foreign_item {
787 #![cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))]
788 ForeignItem::Fn(item) => self.foreign_item_fn(item),
789 ForeignItem::Static(item) => self.foreign_item_static(item),
790 ForeignItem::Type(item) => self.foreign_item_type(item),
791 ForeignItem::Macro(item) => self.foreign_item_macro(item),
792 ForeignItem::Verbatim(item) => self.foreign_item_verbatim(item),
793 _ => unimplemented!("unknown ForeignItem"),
794 }
795 }
796
797 fn foreign_item_fn(&mut self, foreign_item: &ForeignItemFn) {
798 self.outer_attrs(&foreign_item.attrs);
799 self.cbox(INDENT);
800 self.visibility(&foreign_item.vis);
801 self.signature(
802 &foreign_item.sig,
803 #[cfg(feature = "verbatim")]
804 &verbatim::Safety::Disallowed,
805 );
806 self.where_clause_semi(&foreign_item.sig.generics.where_clause);
807 self.end();
808 self.hardbreak();
809 }
810
811 fn foreign_item_static(&mut self, foreign_item: &ForeignItemStatic) {
812 self.outer_attrs(&foreign_item.attrs);
813 self.cbox(0);
814 self.visibility(&foreign_item.vis);
815 self.word("static ");
816 self.static_mutability(&foreign_item.mutability);
817 self.ident(&foreign_item.ident);
818 self.word(": ");
819 self.ty(&foreign_item.ty);
820 self.word(";");
821 self.end();
822 self.hardbreak();
823 }
824
825 fn foreign_item_type(&mut self, foreign_item: &ForeignItemType) {
826 self.outer_attrs(&foreign_item.attrs);
827 self.cbox(0);
828 self.visibility(&foreign_item.vis);
829 self.word("type ");
830 self.ident(&foreign_item.ident);
831 self.generics(&foreign_item.generics);
832 self.word(";");
833 self.end();
834 self.hardbreak();
835 }
836
837 fn foreign_item_macro(&mut self, foreign_item: &ForeignItemMacro) {
838 self.outer_attrs(&foreign_item.attrs);
839 let semicolon = true;
840 self.mac(&foreign_item.mac, None, semicolon);
841 self.hardbreak();
842 }
843
844 #[cfg(not(feature = "verbatim"))]
845 fn foreign_item_verbatim(&mut self, foreign_item: &TokenStream) {
846 if !foreign_item.is_empty() {
847 unimplemented!("ForeignItem::Verbatim `{}`", foreign_item);
848 }
849 self.hardbreak();
850 }
851
852 #[cfg(feature = "verbatim")]
853 fn foreign_item_verbatim(&mut self, tokens: &TokenStream) {
854 use syn::parse::{Parse, ParseStream, Result};
855 use syn::{Abi, Attribute, Token, Visibility};
856 use verbatim::{
857 kw, FlexibleItemFn, FlexibleItemStatic, FlexibleItemType, WhereClauseLocation,
858 };
859
860 enum ForeignItemVerbatim {
861 Empty,
862 Ellipsis,
863 FnFlexible(FlexibleItemFn),
864 StaticFlexible(FlexibleItemStatic),
865 TypeFlexible(FlexibleItemType),
866 }
867
868 fn peek_signature(input: ParseStream) -> bool {
869 let fork = input.fork();
870 fork.parse::<Option<Token![const]>>().is_ok()
871 && fork.parse::<Option<Token![async]>>().is_ok()
872 && ((fork.peek(kw::safe) && fork.parse::<kw::safe>().is_ok())
873 || fork.parse::<Option<Token![unsafe]>>().is_ok())
874 && fork.parse::<Option<Abi>>().is_ok()
875 && fork.peek(Token![fn])
876 }
877
878 impl Parse for ForeignItemVerbatim {
879 fn parse(input: ParseStream) -> Result<Self> {
880 if input.is_empty() {
881 return Ok(ForeignItemVerbatim::Empty);
882 } else if input.peek(Token![...]) {
883 input.parse::<Token![...]>()?;
884 return Ok(ForeignItemVerbatim::Ellipsis);
885 }
886
887 let attrs = input.call(Attribute::parse_outer)?;
888 let vis: Visibility = input.parse()?;
889 let defaultness = false;
890
891 let lookahead = input.lookahead1();
892 if lookahead.peek(Token![fn]) || peek_signature(input) {
893 let flexible_item = FlexibleItemFn::parse(attrs, vis, defaultness, input)?;
894 Ok(ForeignItemVerbatim::FnFlexible(flexible_item))
895 } else if lookahead.peek(Token![static])
896 || ((input.peek(Token![unsafe]) || input.peek(kw::safe))
897 && input.peek2(Token![static]))
898 {
899 let flexible_item = FlexibleItemStatic::parse(attrs, vis, input)?;
900 Ok(ForeignItemVerbatim::StaticFlexible(flexible_item))
901 } else if lookahead.peek(Token![type]) {
902 let flexible_item = FlexibleItemType::parse(
903 attrs,
904 vis,
905 defaultness,
906 input,
907 WhereClauseLocation::Both,
908 )?;
909 Ok(ForeignItemVerbatim::TypeFlexible(flexible_item))
910 } else {
911 Err(lookahead.error())
912 }
913 }
914 }
915
916 let foreign_item: ForeignItemVerbatim = match syn::parse2(tokens.clone()) {
917 Ok(foreign_item) => foreign_item,
918 Err(_) => unimplemented!("ForeignItem::Verbatim `{}`", tokens),
919 };
920
921 match foreign_item {
922 ForeignItemVerbatim::Empty => {
923 self.hardbreak();
924 }
925 ForeignItemVerbatim::Ellipsis => {
926 self.word("...");
927 self.hardbreak();
928 }
929 ForeignItemVerbatim::FnFlexible(foreign_item) => {
930 self.flexible_item_fn(&foreign_item);
931 }
932 ForeignItemVerbatim::StaticFlexible(foreign_item) => {
933 self.flexible_item_static(&foreign_item);
934 }
935 ForeignItemVerbatim::TypeFlexible(foreign_item) => {
936 self.flexible_item_type(&foreign_item);
937 }
938 }
939 }
940
941 fn trait_item(&mut self, trait_item: &TraitItem) {
942 match trait_item {
943 #![cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))]
944 TraitItem::Const(item) => self.trait_item_const(item),
945 TraitItem::Fn(item) => self.trait_item_fn(item),
946 TraitItem::Type(item) => self.trait_item_type(item),
947 TraitItem::Macro(item) => self.trait_item_macro(item),
948 TraitItem::Verbatim(item) => self.trait_item_verbatim(item),
949 _ => unimplemented!("unknown TraitItem"),
950 }
951 }
952
953 fn trait_item_const(&mut self, trait_item: &TraitItemConst) {
954 self.outer_attrs(&trait_item.attrs);
955 self.cbox(0);
956 self.word("const ");
957 self.ident(&trait_item.ident);
958 self.generics(&trait_item.generics);
959 self.word(": ");
960 self.ty(&trait_item.ty);
961 if let Some((_eq_token, default)) = &trait_item.default {
962 self.word(" = ");
963 self.neverbreak();
964 self.expr(default);
965 }
966 self.word(";");
967 self.end();
968 self.hardbreak();
969 }
970
971 fn trait_item_fn(&mut self, trait_item: &TraitItemFn) {
972 self.outer_attrs(&trait_item.attrs);
973 self.cbox(INDENT);
974 self.signature(
975 &trait_item.sig,
976 #[cfg(feature = "verbatim")]
977 &verbatim::Safety::Disallowed,
978 );
979 if let Some(block) = &trait_item.default {
980 self.where_clause_for_body(&trait_item.sig.generics.where_clause);
981 self.word("{");
982 self.hardbreak_if_nonempty();
983 self.inner_attrs(&trait_item.attrs);
984 for stmt in &block.stmts {
985 self.stmt(stmt);
986 }
987 self.offset(-INDENT);
988 self.end();
989 self.word("}");
990 } else {
991 self.where_clause_semi(&trait_item.sig.generics.where_clause);
992 self.end();
993 }
994 self.hardbreak();
995 }
996
997 fn trait_item_type(&mut self, trait_item: &TraitItemType) {
998 self.outer_attrs(&trait_item.attrs);
999 self.cbox(INDENT);
1000 self.word("type ");
1001 self.ident(&trait_item.ident);
1002 self.generics(&trait_item.generics);
1003 for bound in trait_item.bounds.iter().delimited() {
1004 if bound.is_first {
1005 self.word(": ");
1006 } else {
1007 self.space();
1008 self.word("+ ");
1009 }
1010 self.type_param_bound(&bound);
1011 }
1012 if let Some((_eq_token, default)) = &trait_item.default {
1013 self.word(" = ");
1014 self.neverbreak();
1015 self.ibox(-INDENT);
1016 self.ty(default);
1017 self.end();
1018 }
1019 self.where_clause_oneline_semi(&trait_item.generics.where_clause);
1020 self.end();
1021 self.hardbreak();
1022 }
1023
1024 fn trait_item_macro(&mut self, trait_item: &TraitItemMacro) {
1025 self.outer_attrs(&trait_item.attrs);
1026 let semicolon = true;
1027 self.mac(&trait_item.mac, None, semicolon);
1028 self.hardbreak();
1029 }
1030
1031 #[cfg(not(feature = "verbatim"))]
1032 fn trait_item_verbatim(&mut self, trait_item: &TokenStream) {
1033 if !trait_item.is_empty() {
1034 unimplemented!("TraitItem::Verbatim `{}`", trait_item);
1035 }
1036 self.hardbreak();
1037 }
1038
1039 #[cfg(feature = "verbatim")]
1040 fn trait_item_verbatim(&mut self, tokens: &TokenStream) {
1041 use syn::parse::{Parse, ParseStream, Result};
1042 use syn::{Attribute, Ident, Token, Visibility};
1043 use verbatim::{FlexibleItemConst, FlexibleItemType, WhereClauseLocation};
1044
1045 enum TraitItemVerbatim {
1046 Empty,
1047 Ellipsis,
1048 ConstFlexible(FlexibleItemConst),
1049 TypeFlexible(FlexibleItemType),
1050 PubOrDefault(PubOrDefaultTraitItem),
1051 }
1052
1053 struct PubOrDefaultTraitItem {
1054 attrs: Vec<Attribute>,
1055 vis: Visibility,
1056 defaultness: bool,
1057 trait_item: TraitItem,
1058 }
1059
1060 impl Parse for TraitItemVerbatim {
1061 fn parse(input: ParseStream) -> Result<Self> {
1062 if input.is_empty() {
1063 return Ok(TraitItemVerbatim::Empty);
1064 } else if input.peek(Token![...]) {
1065 input.parse::<Token![...]>()?;
1066 return Ok(TraitItemVerbatim::Ellipsis);
1067 }
1068
1069 let attrs = input.call(Attribute::parse_outer)?;
1070 let vis: Visibility = input.parse()?;
1071 let defaultness = input.parse::<Option<Token![default]>>()?.is_some();
1072
1073 let lookahead = input.lookahead1();
1074 if lookahead.peek(Token![const]) && (input.peek2(Ident) || input.peek2(Token![_])) {
1075 let flexible_item = FlexibleItemConst::parse(attrs, vis, defaultness, input)?;
1076 Ok(TraitItemVerbatim::ConstFlexible(flexible_item))
1077 } else if lookahead.peek(Token![type]) {
1078 let flexible_item = FlexibleItemType::parse(
1079 attrs,
1080 vis,
1081 defaultness,
1082 input,
1083 WhereClauseLocation::AfterEq,
1084 )?;
1085 Ok(TraitItemVerbatim::TypeFlexible(flexible_item))
1086 } else if (input.peek(Token![const])
1087 || lookahead.peek(Token![async])
1088 || lookahead.peek(Token![unsafe])
1089 || lookahead.peek(Token![extern])
1090 || lookahead.peek(Token![fn]))
1091 && (!matches!(vis, Visibility::Inherited) || defaultness)
1092 {
1093 Ok(TraitItemVerbatim::PubOrDefault(PubOrDefaultTraitItem {
1094 attrs,
1095 vis,
1096 defaultness,
1097 trait_item: input.parse()?,
1098 }))
1099 } else {
1100 Err(lookahead.error())
1101 }
1102 }
1103 }
1104
1105 let impl_item: TraitItemVerbatim = match syn::parse2(tokens.clone()) {
1106 Ok(impl_item) => impl_item,
1107 Err(_) => unimplemented!("TraitItem::Verbatim `{}`", tokens),
1108 };
1109
1110 match impl_item {
1111 TraitItemVerbatim::Empty => {
1112 self.hardbreak();
1113 }
1114 TraitItemVerbatim::Ellipsis => {
1115 self.word("...");
1116 self.hardbreak();
1117 }
1118 TraitItemVerbatim::ConstFlexible(trait_item) => {
1119 self.flexible_item_const(&trait_item);
1120 }
1121 TraitItemVerbatim::TypeFlexible(trait_item) => {
1122 self.flexible_item_type(&trait_item);
1123 }
1124 TraitItemVerbatim::PubOrDefault(trait_item) => {
1125 self.outer_attrs(&trait_item.attrs);
1126 self.visibility(&trait_item.vis);
1127 if trait_item.defaultness {
1128 self.word("default ");
1129 }
1130 self.trait_item(&trait_item.trait_item);
1131 }
1132 }
1133 }
1134
1135 fn impl_item(&mut self, impl_item: &ImplItem) {
1136 match impl_item {
1137 #![cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))]
1138 ImplItem::Const(item) => self.impl_item_const(item),
1139 ImplItem::Fn(item) => self.impl_item_fn(item),
1140 ImplItem::Type(item) => self.impl_item_type(item),
1141 ImplItem::Macro(item) => self.impl_item_macro(item),
1142 ImplItem::Verbatim(item) => self.impl_item_verbatim(item),
1143 _ => unimplemented!("unknown ImplItem"),
1144 }
1145 }
1146
1147 fn impl_item_const(&mut self, impl_item: &ImplItemConst) {
1148 self.outer_attrs(&impl_item.attrs);
1149 self.cbox(0);
1150 self.visibility(&impl_item.vis);
1151 if impl_item.defaultness.is_some() {
1152 self.word("default ");
1153 }
1154 self.word("const ");
1155 self.ident(&impl_item.ident);
1156 self.generics(&impl_item.generics);
1157 self.word(": ");
1158 self.ty(&impl_item.ty);
1159 self.word(" = ");
1160 self.neverbreak();
1161 self.expr(&impl_item.expr);
1162 self.word(";");
1163 self.end();
1164 self.hardbreak();
1165 }
1166
1167 fn impl_item_fn(&mut self, impl_item: &ImplItemFn) {
1168 self.outer_attrs(&impl_item.attrs);
1169 self.cbox(INDENT);
1170 self.visibility(&impl_item.vis);
1171 if impl_item.defaultness.is_some() {
1172 self.word("default ");
1173 }
1174 self.signature(
1175 &impl_item.sig,
1176 #[cfg(feature = "verbatim")]
1177 &verbatim::Safety::Disallowed,
1178 );
1179 self.where_clause_for_body(&impl_item.sig.generics.where_clause);
1180 self.word("{");
1181 self.hardbreak_if_nonempty();
1182 self.inner_attrs(&impl_item.attrs);
1183 for stmt in &impl_item.block.stmts {
1184 self.stmt(stmt);
1185 }
1186 self.offset(-INDENT);
1187 self.end();
1188 self.word("}");
1189 self.hardbreak();
1190 }
1191
1192 fn impl_item_type(&mut self, impl_item: &ImplItemType) {
1193 self.outer_attrs(&impl_item.attrs);
1194 self.cbox(INDENT);
1195 self.visibility(&impl_item.vis);
1196 if impl_item.defaultness.is_some() {
1197 self.word("default ");
1198 }
1199 self.word("type ");
1200 self.ident(&impl_item.ident);
1201 self.generics(&impl_item.generics);
1202 self.word(" = ");
1203 self.neverbreak();
1204 self.ibox(-INDENT);
1205 self.ty(&impl_item.ty);
1206 self.end();
1207 self.where_clause_oneline_semi(&impl_item.generics.where_clause);
1208 self.end();
1209 self.hardbreak();
1210 }
1211
1212 fn impl_item_macro(&mut self, impl_item: &ImplItemMacro) {
1213 self.outer_attrs(&impl_item.attrs);
1214 let semicolon = true;
1215 self.mac(&impl_item.mac, None, semicolon);
1216 self.hardbreak();
1217 }
1218
1219 #[cfg(not(feature = "verbatim"))]
1220 fn impl_item_verbatim(&mut self, impl_item: &TokenStream) {
1221 if !impl_item.is_empty() {
1222 unimplemented!("ImplItem::Verbatim `{}`", impl_item);
1223 }
1224 self.hardbreak();
1225 }
1226
1227 #[cfg(feature = "verbatim")]
1228 fn impl_item_verbatim(&mut self, tokens: &TokenStream) {
1229 use syn::parse::{Parse, ParseStream, Result};
1230 use syn::{Attribute, Ident, Token, Visibility};
1231 use verbatim::{FlexibleItemConst, FlexibleItemFn, FlexibleItemType, WhereClauseLocation};
1232
1233 enum ImplItemVerbatim {
1234 Empty,
1235 Ellipsis,
1236 ConstFlexible(FlexibleItemConst),
1237 FnFlexible(FlexibleItemFn),
1238 TypeFlexible(FlexibleItemType),
1239 }
1240
1241 impl Parse for ImplItemVerbatim {
1242 fn parse(input: ParseStream) -> Result<Self> {
1243 if input.is_empty() {
1244 return Ok(ImplItemVerbatim::Empty);
1245 } else if input.peek(Token![...]) {
1246 input.parse::<Token![...]>()?;
1247 return Ok(ImplItemVerbatim::Ellipsis);
1248 }
1249
1250 let attrs = input.call(Attribute::parse_outer)?;
1251 let vis: Visibility = input.parse()?;
1252 let defaultness = input.parse::<Option<Token![default]>>()?.is_some();
1253
1254 let lookahead = input.lookahead1();
1255 if lookahead.peek(Token![const]) && (input.peek2(Ident) || input.peek2(Token![_])) {
1256 let flexible_item = FlexibleItemConst::parse(attrs, vis, defaultness, input)?;
1257 Ok(ImplItemVerbatim::ConstFlexible(flexible_item))
1258 } else if input.peek(Token![const])
1259 || lookahead.peek(Token![async])
1260 || lookahead.peek(Token![unsafe])
1261 || lookahead.peek(Token![extern])
1262 || lookahead.peek(Token![fn])
1263 {
1264 let flexible_item = FlexibleItemFn::parse(attrs, vis, defaultness, input)?;
1265 Ok(ImplItemVerbatim::FnFlexible(flexible_item))
1266 } else if lookahead.peek(Token![type]) {
1267 let flexible_item = FlexibleItemType::parse(
1268 attrs,
1269 vis,
1270 defaultness,
1271 input,
1272 WhereClauseLocation::AfterEq,
1273 )?;
1274 Ok(ImplItemVerbatim::TypeFlexible(flexible_item))
1275 } else {
1276 Err(lookahead.error())
1277 }
1278 }
1279 }
1280
1281 let impl_item: ImplItemVerbatim = match syn::parse2(tokens.clone()) {
1282 Ok(impl_item) => impl_item,
1283 Err(_) => unimplemented!("ImplItem::Verbatim `{}`", tokens),
1284 };
1285
1286 match impl_item {
1287 ImplItemVerbatim::Empty => {
1288 self.hardbreak();
1289 }
1290 ImplItemVerbatim::Ellipsis => {
1291 self.word("...");
1292 self.hardbreak();
1293 }
1294 ImplItemVerbatim::ConstFlexible(impl_item) => {
1295 self.flexible_item_const(&impl_item);
1296 }
1297 ImplItemVerbatim::FnFlexible(impl_item) => {
1298 self.flexible_item_fn(&impl_item);
1299 }
1300 ImplItemVerbatim::TypeFlexible(impl_item) => {
1301 self.flexible_item_type(&impl_item);
1302 }
1303 }
1304 }
1305
1306 fn signature(
1307 &mut self,
1308 signature: &Signature,
1309 #[cfg(feature = "verbatim")] safety: &verbatim::Safety,
1310 ) {
1311 if signature.constness.is_some() {
1312 self.word("const ");
1313 }
1314 if signature.asyncness.is_some() {
1315 self.word("async ");
1316 }
1317 #[cfg(feature = "verbatim")]
1318 {
1319 if let verbatim::Safety::Disallowed = safety {
1320 if signature.unsafety.is_some() {
1321 self.word("unsafe ");
1322 }
1323 } else {
1324 self.safety(safety);
1325 }
1326 }
1327 #[cfg(not(feature = "verbatim"))]
1328 {
1329 if signature.unsafety.is_some() {
1330 self.word("unsafe ");
1331 }
1332 }
1333 if let Some(abi) = &signature.abi {
1334 self.abi(abi);
1335 }
1336 self.word("fn ");
1337 self.ident(&signature.ident);
1338 self.generics(&signature.generics);
1339 self.word("(");
1340 self.neverbreak();
1341 self.cbox(0);
1342 self.zerobreak();
1343 for input in signature.inputs.iter().delimited() {
1344 self.fn_arg(&input);
1345 let is_last = input.is_last && signature.variadic.is_none();
1346 self.trailing_comma(is_last);
1347 }
1348 if let Some(variadic) = &signature.variadic {
1349 self.variadic(variadic);
1350 self.zerobreak();
1351 }
1352 self.offset(-INDENT);
1353 self.end();
1354 self.word(")");
1355 self.cbox(-INDENT);
1356 self.return_type(&signature.output);
1357 self.end();
1358 }
1359
1360 fn fn_arg(&mut self, fn_arg: &FnArg) {
1361 match fn_arg {
1362 FnArg::Receiver(receiver) => self.receiver(receiver),
1363 FnArg::Typed(pat_type) => self.pat_type(pat_type),
1364 }
1365 }
1366
1367 fn receiver(&mut self, receiver: &Receiver) {
1368 self.outer_attrs(&receiver.attrs);
1369 if let Some((_ampersand, lifetime)) = &receiver.reference {
1370 self.word("&");
1371 if let Some(lifetime) = lifetime {
1372 self.lifetime(lifetime);
1373 self.nbsp();
1374 }
1375 }
1376 if receiver.mutability.is_some() {
1377 self.word("mut ");
1378 }
1379 self.word("self");
1380 if receiver.colon_token.is_some() {
1381 self.word(": ");
1382 self.ty(&receiver.ty);
1383 } else {
1384 let consistent = match (&receiver.reference, &receiver.mutability, &*receiver.ty) {
1385 (Some(_), mutability, Type::Reference(ty)) => {
1386 mutability.is_some() == ty.mutability.is_some()
1387 && match &*ty.elem {
1388 Type::Path(ty) => ty.qself.is_none() && ty.path.is_ident("Self"),
1389 _ => false,
1390 }
1391 }
1392 (None, _, Type::Path(ty)) => ty.qself.is_none() && ty.path.is_ident("Self"),
1393 _ => false,
1394 };
1395 if !consistent {
1396 self.word(": ");
1397 self.ty(&receiver.ty);
1398 }
1399 }
1400 }
1401
1402 fn variadic(&mut self, variadic: &Variadic) {
1403 self.outer_attrs(&variadic.attrs);
1404 if let Some((pat, _colon)) = &variadic.pat {
1405 self.pat(pat);
1406 self.word(": ");
1407 }
1408 self.word("...");
1409 }
1410
1411 fn static_mutability(&mut self, mutability: &StaticMutability) {
1412 match mutability {
1413 #![cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))]
1414 StaticMutability::Mut(_) => self.word("mut "),
1415 StaticMutability::None => {}
1416 _ => unimplemented!("unknown StaticMutability"),
1417 }
1418 }
1419}
1420
1421#[cfg(feature = "verbatim")]
1422mod verbatim {
1423 use crate::algorithm::Printer;
1424 use crate::iter::IterDelimited;
1425 use crate::INDENT;
1426 use syn::ext::IdentExt;
1427 use syn::parse::{Parse, ParseStream, Result};
1428 use syn::{
1429 braced, token, Attribute, Block, Expr, Generics, Ident, Signature, StaticMutability, Stmt,
1430 Token, Type, TypeParamBound, Visibility, WhereClause,
1431 };
1432
1433 pub mod kw {
1434 syn::custom_keyword!(safe);
1435 }
1436
1437 pub struct FlexibleItemConst {
1438 pub attrs: Vec<Attribute>,
1439 pub vis: Visibility,
1440 pub defaultness: bool,
1441 pub ident: Ident,
1442 pub generics: Generics,
1443 pub ty: Type,
1444 pub value: Option<Expr>,
1445 }
1446
1447 pub struct FlexibleItemFn {
1448 pub attrs: Vec<Attribute>,
1449 pub vis: Visibility,
1450 pub defaultness: bool,
1451 pub safety: Safety,
1452 pub sig: Signature,
1453 pub body: Option<Vec<Stmt>>,
1454 }
1455
1456 pub struct FlexibleItemStatic {
1457 pub attrs: Vec<Attribute>,
1458 pub vis: Visibility,
1459 pub safety: Safety,
1460 pub mutability: StaticMutability,
1461 pub ident: Ident,
1462 pub ty: Option<Type>,
1463 pub expr: Option<Expr>,
1464 }
1465
1466 pub struct FlexibleItemType {
1467 pub attrs: Vec<Attribute>,
1468 pub vis: Visibility,
1469 pub defaultness: bool,
1470 pub ident: Ident,
1471 pub generics: Generics,
1472 pub bounds: Vec<TypeParamBound>,
1473 pub definition: Option<Type>,
1474 pub where_clause_after_eq: Option<WhereClause>,
1475 }
1476
1477 pub enum Safety {
1478 Unsafe,
1479 Safe,
1480 Default,
1481 Disallowed,
1482 }
1483
1484 pub enum WhereClauseLocation {
1485 BeforeEq,
1487 AfterEq,
1489 Both,
1491 }
1492
1493 impl FlexibleItemConst {
1494 pub fn parse(
1495 attrs: Vec<Attribute>,
1496 vis: Visibility,
1497 defaultness: bool,
1498 input: ParseStream,
1499 ) -> Result<Self> {
1500 input.parse::<Token![const]>()?;
1501 let ident = input.call(Ident::parse_any)?;
1502 let mut generics: Generics = input.parse()?;
1503 input.parse::<Token![:]>()?;
1504 let ty: Type = input.parse()?;
1505 let value = if input.parse::<Option<Token![=]>>()?.is_some() {
1506 let expr: Expr = input.parse()?;
1507 Some(expr)
1508 } else {
1509 None
1510 };
1511 generics.where_clause = input.parse()?;
1512 input.parse::<Token![;]>()?;
1513
1514 Ok(FlexibleItemConst {
1515 attrs,
1516 vis,
1517 defaultness,
1518 ident,
1519 generics,
1520 ty,
1521 value,
1522 })
1523 }
1524 }
1525
1526 impl FlexibleItemFn {
1527 pub fn parse(
1528 mut attrs: Vec<Attribute>,
1529 vis: Visibility,
1530 defaultness: bool,
1531 input: ParseStream,
1532 ) -> Result<Self> {
1533 let constness: Option<Token![const]> = input.parse()?;
1534 let asyncness: Option<Token![async]> = input.parse()?;
1535 let safety: Safety = input.parse()?;
1536
1537 let lookahead = input.lookahead1();
1538 let sig: Signature = if lookahead.peek(Token![extern]) || lookahead.peek(Token![fn]) {
1539 input.parse()?
1540 } else {
1541 return Err(lookahead.error());
1542 };
1543
1544 let lookahead = input.lookahead1();
1545 let body = if lookahead.peek(Token![;]) {
1546 input.parse::<Token![;]>()?;
1547 None
1548 } else if lookahead.peek(token::Brace) {
1549 let content;
1550 braced!(content in input);
1551 attrs.extend(content.call(Attribute::parse_inner)?);
1552 Some(content.call(Block::parse_within)?)
1553 } else {
1554 return Err(lookahead.error());
1555 };
1556
1557 Ok(FlexibleItemFn {
1558 attrs,
1559 vis,
1560 defaultness,
1561 safety,
1562 sig: Signature {
1563 constness,
1564 asyncness,
1565 unsafety: None,
1566 ..sig
1567 },
1568 body,
1569 })
1570 }
1571 }
1572
1573 impl FlexibleItemStatic {
1574 pub fn parse(attrs: Vec<Attribute>, vis: Visibility, input: ParseStream) -> Result<Self> {
1575 let safety: Safety = input.parse()?;
1576 input.parse::<Token![static]>()?;
1577 let mutability: StaticMutability = input.parse()?;
1578 let ident = input.parse()?;
1579
1580 let lookahead = input.lookahead1();
1581 let has_type = lookahead.peek(Token![:]);
1582 let has_expr = lookahead.peek(Token![=]);
1583 if !has_type && !has_expr {
1584 return Err(lookahead.error());
1585 }
1586
1587 let ty: Option<Type> = if has_type {
1588 input.parse::<Token![:]>()?;
1589 input.parse().map(Some)?
1590 } else {
1591 None
1592 };
1593
1594 let expr: Option<Expr> = if input.parse::<Option<Token![=]>>()?.is_some() {
1595 input.parse().map(Some)?
1596 } else {
1597 None
1598 };
1599
1600 input.parse::<Token![;]>()?;
1601
1602 Ok(FlexibleItemStatic {
1603 attrs,
1604 vis,
1605 safety,
1606 mutability,
1607 ident,
1608 ty,
1609 expr,
1610 })
1611 }
1612 }
1613
1614 impl FlexibleItemType {
1615 pub fn parse(
1616 attrs: Vec<Attribute>,
1617 vis: Visibility,
1618 defaultness: bool,
1619 input: ParseStream,
1620 where_clause_location: WhereClauseLocation,
1621 ) -> Result<Self> {
1622 input.parse::<Token![type]>()?;
1623 let ident: Ident = input.parse()?;
1624 let mut generics: Generics = input.parse()?;
1625
1626 let mut bounds = Vec::new();
1627 if input.parse::<Option<Token![:]>>()?.is_some() {
1628 loop {
1629 if input.peek(Token![where]) || input.peek(Token![=]) || input.peek(Token![;]) {
1630 break;
1631 }
1632 bounds.push(input.parse::<TypeParamBound>()?);
1633 if input.peek(Token![where]) || input.peek(Token![=]) || input.peek(Token![;]) {
1634 break;
1635 }
1636 input.parse::<Token![+]>()?;
1637 }
1638 }
1639
1640 match where_clause_location {
1641 WhereClauseLocation::BeforeEq | WhereClauseLocation::Both => {
1642 generics.where_clause = input.parse()?;
1643 }
1644 WhereClauseLocation::AfterEq => {}
1645 }
1646
1647 let definition = if input.parse::<Option<Token![=]>>()?.is_some() {
1648 Some(input.parse()?)
1649 } else {
1650 None
1651 };
1652
1653 let where_clause_after_eq = match where_clause_location {
1654 WhereClauseLocation::AfterEq | WhereClauseLocation::Both
1655 if generics.where_clause.is_none() =>
1656 {
1657 input.parse()?
1658 }
1659 _ => None,
1660 };
1661
1662 input.parse::<Token![;]>()?;
1663
1664 Ok(FlexibleItemType {
1665 attrs,
1666 vis,
1667 defaultness,
1668 ident,
1669 generics,
1670 bounds,
1671 definition,
1672 where_clause_after_eq,
1673 })
1674 }
1675 }
1676
1677 impl Parse for Safety {
1678 fn parse(input: ParseStream) -> Result<Self> {
1679 if input.peek(Token![unsafe]) {
1680 input.parse::<Token![unsafe]>()?;
1681 Ok(Safety::Unsafe)
1682 } else if input.peek(kw::safe) {
1683 input.parse::<kw::safe>()?;
1684 Ok(Safety::Safe)
1685 } else {
1686 Ok(Safety::Default)
1687 }
1688 }
1689 }
1690
1691 impl Printer {
1692 pub fn flexible_item_const(&mut self, item: &FlexibleItemConst) {
1693 self.outer_attrs(&item.attrs);
1694 self.cbox(INDENT);
1695 self.visibility(&item.vis);
1696 if item.defaultness {
1697 self.word("default ");
1698 }
1699 self.word("const ");
1700 self.ident(&item.ident);
1701 self.generics(&item.generics);
1702 self.word(": ");
1703 self.cbox(-INDENT);
1704 self.ty(&item.ty);
1705 self.end();
1706 if let Some(value) = &item.value {
1707 self.word(" = ");
1708 self.neverbreak();
1709 self.ibox(-INDENT);
1710 self.expr(value);
1711 self.end();
1712 }
1713 self.where_clause_oneline_semi(&item.generics.where_clause);
1714 self.end();
1715 self.hardbreak();
1716 }
1717
1718 pub fn flexible_item_fn(&mut self, item: &FlexibleItemFn) {
1719 self.outer_attrs(&item.attrs);
1720 self.cbox(INDENT);
1721 self.visibility(&item.vis);
1722 if item.defaultness {
1723 self.word("default ");
1724 }
1725 self.signature(&item.sig, &item.safety);
1726 if let Some(body) = &item.body {
1727 self.where_clause_for_body(&item.sig.generics.where_clause);
1728 self.word("{");
1729 self.hardbreak_if_nonempty();
1730 self.inner_attrs(&item.attrs);
1731 for stmt in body {
1732 self.stmt(stmt);
1733 }
1734 self.offset(-INDENT);
1735 self.end();
1736 self.word("}");
1737 } else {
1738 self.where_clause_semi(&item.sig.generics.where_clause);
1739 self.end();
1740 }
1741 self.hardbreak();
1742 }
1743
1744 pub fn flexible_item_static(&mut self, item: &FlexibleItemStatic) {
1745 self.outer_attrs(&item.attrs);
1746 self.cbox(0);
1747 self.visibility(&item.vis);
1748 self.safety(&item.safety);
1749 self.word("static ");
1750 self.static_mutability(&item.mutability);
1751 self.ident(&item.ident);
1752 if let Some(ty) = &item.ty {
1753 self.word(": ");
1754 self.ty(ty);
1755 }
1756 if let Some(expr) = &item.expr {
1757 self.word(" = ");
1758 self.neverbreak();
1759 self.expr(expr);
1760 }
1761 self.word(";");
1762 self.end();
1763 self.hardbreak();
1764 }
1765
1766 pub fn flexible_item_type(&mut self, item: &FlexibleItemType) {
1767 self.outer_attrs(&item.attrs);
1768 self.cbox(INDENT);
1769 self.visibility(&item.vis);
1770 if item.defaultness {
1771 self.word("default ");
1772 }
1773 self.word("type ");
1774 self.ident(&item.ident);
1775 self.generics(&item.generics);
1776 for bound in item.bounds.iter().delimited() {
1777 if bound.is_first {
1778 self.word(": ");
1779 } else {
1780 self.space();
1781 self.word("+ ");
1782 }
1783 self.type_param_bound(&bound);
1784 }
1785 if let Some(definition) = &item.definition {
1786 self.where_clause_oneline(&item.generics.where_clause);
1787 self.word("= ");
1788 self.neverbreak();
1789 self.ibox(-INDENT);
1790 self.ty(definition);
1791 self.end();
1792 self.where_clause_oneline_semi(&item.where_clause_after_eq);
1793 } else {
1794 self.where_clause_oneline_semi(&item.generics.where_clause);
1795 }
1796 self.end();
1797 self.hardbreak();
1798 }
1799
1800 pub fn safety(&mut self, safety: &Safety) {
1801 match safety {
1802 Safety::Unsafe => self.word("unsafe "),
1803 Safety::Safe => self.word("safe "),
1804 Safety::Default => {}
1805 Safety::Disallowed => unreachable!(),
1806 }
1807 }
1808 }
1809}