+ pub fn visit_enum(&mut self,
+ ident: ast::Ident,
+ vis: ast::Visibility,
+ enum_def: &ast::EnumDef,
+ generics: &ast::Generics,
+ span: Span)
+ {
+ let header_str = self.format_header("enum", ident, vis);
+ self.changes.push_str_span(span, &header_str);
+
+ let enum_snippet = self.snippet(span);
+ // FIXME this will give incorrect results if there is a { in a comment.
+ let body_start = span.lo + BytePos(enum_snippet.find('{').unwrap() as u32 + 1);
+ let generics_str = self.format_generics(generics, body_start);
+ self.changes.push_str_span(span, &generics_str);
+
+ self.last_pos = body_start;
+ self.block_indent += config!(tab_spaces);
+ for (i, f) in enum_def.variants.iter().enumerate() {
+ let next_span_start: BytePos = if i == enum_def.variants.len() - 1 {
+ span.hi
+ } else {
+ enum_def.variants[i + 1].span.lo
+ };
+
+ self.visit_variant(f, i == enum_def.variants.len() - 1, next_span_start);
+ }
+ self.block_indent -= config!(tab_spaces);
+
+ self.format_missing_with_indent(span.lo + BytePos(enum_snippet.rfind('}').unwrap() as u32));
+ self.changes.push_str_span(span, "}");
+ }
+
+ // Variant of an enum
+ fn visit_variant(&mut self,
+ field: &ast::Variant,
+ last_field: bool,
+ next_span_start: BytePos)
+ {
+ if self.visit_attrs(&field.node.attrs) {
+ return;
+ }
+
+ if let ast::VariantKind::TupleVariantKind(ref types) = field.node.kind {
+ self.format_missing_with_indent(field.span.lo);
+
+ let vis = format_visibility(field.node.vis);
+ self.changes.push_str_span(field.span, vis);
+ let name = field.node.name.to_string();
+ self.changes.push_str_span(field.span, &name);
+
+ let mut result = String::new();
+
+ if types.len() > 0 {
+ let comments = self.make_comments_for_list(Vec::new(),
+ types.iter().map(|arg| arg.ty.span),
+ ",",
+ ")",
+ |span| span.lo,
+ |span| span.hi,
+ next_span_start);
+
+ let type_strings: Vec<_> = types.iter()
+ .map(|arg| pprust::ty_to_string(&arg.ty))
+ .zip(comments.into_iter())
+ .collect();
+
+ result.push('(');
+
+ let indent = self.block_indent
+ + vis.len()
+ + field.node.name.to_string().len()
+ + 1; // 1 = (
+
+ let comma_cost = if config!(enum_trailing_comma) { 1 } else { 0 };
+ let budget = config!(ideal_width) - indent - comma_cost - 1; // 1 = )
+
+ let fmt = ListFormatting {
+ tactic: ListTactic::HorizontalVertical,
+ separator: ",",
+ trailing_separator: SeparatorTactic::Never,
+ indent: indent,
+ h_width: budget,
+ v_width: budget,
+ };
+ result.push_str(&write_list(&type_strings, &fmt));
+ result.push(')');
+ }
+
+ if let Some(ref expr) = field.node.disr_expr {
+ result.push_str(" = ");
+ let expr_snippet = self.snippet(expr.span);
+ result.push_str(&expr_snippet);
+
+ // Make sure we do not exceed column limit
+ // 4 = " = ,"
+ assert!(config!(max_width) >= vis.len() + name.len() + expr_snippet.len() + 4,
+ "Enum variant exceeded column limit");
+ }
+
+ self.changes.push_str_span(field.span, &result);
+
+ if !last_field || config!(enum_trailing_comma) {
+ self.changes.push_str_span(field.span, ",");
+ }
+ }
+
+ // TODO: deal with struct-like variants
+
+ self.last_pos = field.span.hi + BytePos(1);
+ }
+