- **Default value**: `"Back"`
- **Possible values**: `"Back"`, `"Front"`
-#### `"Back"`
+#### `"Back"`:
```rust
match m {
}
```
-#### `Front`
+#### `Front`:
```rust
match m {
See also [`error_on_line_overflow`](#error_on_line_overflow).
-## `multiline_closure_forces_block`
+## `merge_derives`
-Force multiline closure bodies to be wrapped in a block
+Merge multiple derives into a single one.
-- **Default value**: `false`
-- **Possible values**: `false`, `true`
+- **Default value**: `true`
+- **Possible values**: `true`, `false`
+
+*Note*: The merged derives will be put after all other attributes or doc comments.
+
+#### `true`:
+
+```rust
+#[derive(Eq, PartialEq, Debug, Copy, Clone)]
+pub enum Foo {}
+```
#### `false`:
```rust
-result.and_then(|maybe_value| match maybe_value {
- None => ...,
- Some(value) => ...,
-})
+#[derive(Eq, PartialEq)]
+#[derive(Debug)]
+#[derive(Copy, Clone)]
+pub enum Foo {}
```
+## `multiline_closure_forces_block`
+
+Force multiline closure bodies to be wrapped in a block
+
+- **Default value**: `false`
+- **Possible values**: `false`, `true`
+
#### `true`:
```rust
+
result.and_then(|maybe_value| {
match maybe_value {
None => ...,
})
```
+#### `false`:
+
+```rust
+result.and_then(|maybe_value| match maybe_value {
+ None => ...,
+ Some(value) => ...,
+})
+```
+
## `multiline_match_arm_forces_block`
Force multiline match arm bodies to be wrapped in a block
"Force multiline closure bodies to be wrapped in a block";
multiline_match_arm_forces_block: bool, false,
"Force multiline match arm bodies to be wrapped in a block";
+ merge_derives: bool, true, "Merge multiple `#[derive(...)]` into a single one";
}
#[cfg(test)]
use rewrite::RewriteContext;
use utils::{first_line_width, last_line_width, mk_sp};
-#[derive(Eq, PartialEq, Debug, Copy, Clone)]
/// Formatting tactic for lists. This will be cast down to a
/// DefinitiveListTactic depending on the number and length of the items and
/// their comments.
+#[derive(Eq, PartialEq, Debug, Copy, Clone)]
pub enum ListTactic {
// One item per row.
Vertical,
}
}
-#[derive(Eq, PartialEq, Debug, Copy, Clone)]
/// The definitive formatting tactic for lists.
+#[derive(Eq, PartialEq, Debug, Copy, Clone)]
pub enum DefinitiveListTactic {
Vertical,
Horizontal,
}
let indent = shape.indent.to_string(context.config);
+ let mut derive_args = Vec::new();
+
for (i, a) in self.iter().enumerate() {
let a_str = try_opt!(a.rewrite(context, shape));
}
// Write the attribute itself.
- result.push_str(&a_str);
+ if context.config.merge_derives() {
+ if let Some(mut args) = get_derive_args(context, a) {
+ // If the attribute is `#[derive(...)]`, take the arguments and skip rewriting.
+ // We will merge the all arguments into a single `#[derive(...)]` at last.
+ derive_args.append(&mut args);
+ } else {
+ result.push_str(&a_str);
+
+ if i < self.len() - 1 {
+ result.push('\n');
+ }
+ }
+ } else {
+ result.push_str(&a_str);
- if i < self.len() - 1 {
+ if i < self.len() - 1 {
+ result.push('\n');
+ }
+ }
+ }
+
+ // Add merged `#[derive(...)]` at last.
+ if context.config.merge_derives() && !derive_args.is_empty() {
+ if !result.is_empty() && !result.ends_with('\n') {
+ result.push_str(&indent);
result.push('\n');
}
+ result.push_str(&format!("#[derive({})]", derive_args.join(", ")));
}
Some(result)
}
}
+
+/// Returns the arguments of `#[derive(...)]`.
+fn get_derive_args(context: &RewriteContext, attr: &ast::Attribute) -> Option<Vec<String>> {
+ attr.meta().and_then(|meta_item| match meta_item.node {
+ ast::MetaItemKind::List(ref args) if meta_item.name.as_str() == "derive" => {
+ // Every argument of `derive` should be `NestedMetaItemKind::Literal`.
+ Some(
+ args.iter()
+ .map(|a| context.snippet(a.span))
+ .collect::<Vec<_>>(),
+ )
+ }
+ _ => None,
+ })
+}
--- /dev/null
+// rustfmt-merge_derives: true
+// Merge multiple derives to a single one.
+
+#[bar]
+#[derive(Eq, PartialEq)]
+#[foo]
+#[derive(Debug)]
+#[foobar]
+#[derive(Copy, Clone)]
+pub enum Foo {}
--- /dev/null
+// rustfmt-merge_derives: true
+// Merge multiple derives to a single one.
+
+#[bar]
+#[foo]
+#[foobar]
+#[derive(Eq, PartialEq, Debug, Copy, Clone)]
+pub enum Foo {}