Skip to content

Commit e16d4f3

Browse files
msmorgancalebcartwright
authored andcommitted
Add imports_granularity="Item".
This option splits all imports into their own `use` statement.
1 parent fec65a6 commit e16d4f3

File tree

6 files changed

+81
-9
lines changed

6 files changed

+81
-9
lines changed

Diff for: Configurations.md

+16-1
Original file line numberDiff line numberDiff line change
@@ -1710,7 +1710,7 @@ pub enum Foo {}
17101710
Merge together related imports based on their paths.
17111711

17121712
- **Default value**: `Preserve`
1713-
- **Possible values**: `Preserve`, `Crate`, `Module`
1713+
- **Possible values**: `Preserve`, `Crate`, `Module`, `Item`
17141714
- **Stable**: No
17151715

17161716
#### `Preserve` (default):
@@ -1749,6 +1749,21 @@ use foo::{a, b, c};
17491749
use qux::{h, i};
17501750
```
17511751

1752+
#### `Item`:
1753+
1754+
Flatten imports so that each has its own `use` statement.
1755+
1756+
```rust
1757+
use foo::a;
1758+
use foo::b;
1759+
use foo::b::f;
1760+
use foo::b::g;
1761+
use foo::c;
1762+
use foo::d::e;
1763+
use qux::h;
1764+
use qux::i;
1765+
```
1766+
17521767
## `merge_imports`
17531768

17541769
This option is deprecated. Use `imports_granularity = "Crate"` instead.

Diff for: src/config/options.rs

+2
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,8 @@ pub enum ImportGranularity {
128128
Crate,
129129
/// Use one `use` statement per module.
130130
Module,
131+
/// Use one `use` statement per imported item.
132+
Item,
131133
}
132134

133135
#[config_type]

Diff for: src/formatting/imports.rs

+37
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,24 @@ pub(crate) fn merge_use_trees(use_trees: Vec<UseTree>, merge_by: SharedPrefix) -
182182
result
183183
}
184184

185+
pub(crate) fn flatten_use_trees(use_trees: Vec<UseTree>) -> Vec<UseTree> {
186+
use_trees
187+
.into_iter()
188+
.flat_map(UseTree::flatten)
189+
.map(|mut tree| {
190+
// If a path ends in `::self`, rewrite it to `::{self}`.
191+
if let Some(UseSegment::Slf(..)) = tree.path.last() {
192+
let self_segment = tree.path.pop().unwrap();
193+
tree.path.push(UseSegment::List(vec![UseTree::from_path(
194+
vec![self_segment],
195+
DUMMY_SP,
196+
)]));
197+
}
198+
tree
199+
})
200+
.collect()
201+
}
202+
185203
impl fmt::Debug for UseTree {
186204
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
187205
fmt::Display::fmt(self, f)
@@ -1068,6 +1086,25 @@ mod test {
10681086
);
10691087
}
10701088

1089+
#[test]
1090+
fn test_flatten_use_trees() {
1091+
assert_eq!(
1092+
flatten_use_trees(parse_use_trees!["foo::{a::{b, c}, d::e}"]),
1093+
parse_use_trees!["foo::a::b", "foo::a::c", "foo::d::e"]
1094+
);
1095+
1096+
assert_eq!(
1097+
flatten_use_trees(parse_use_trees!["foo::{self, a, b::{c, d}, e::*}"]),
1098+
parse_use_trees![
1099+
"foo::{self}",
1100+
"foo::a",
1101+
"foo::b::c",
1102+
"foo::b::d",
1103+
"foo::e::*"
1104+
]
1105+
);
1106+
}
1107+
10711108
#[test]
10721109
fn test_use_tree_flatten() {
10731110
assert_eq!(

Diff for: src/formatting/reorder.rs

+7-8
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use rustc_ast::ast;
1212
use rustc_span::{symbol::sym, Span};
1313

1414
use crate::config::{Config, GroupImportsTactic, ImportGranularity};
15-
use crate::formatting::imports::UseSegment;
15+
use crate::formatting::imports::{flatten_use_trees, UseSegment};
1616
use crate::formatting::modules::{get_mod_inner_attrs, FileModMap};
1717
use crate::formatting::{
1818
imports::{merge_use_trees, UseTree},
@@ -228,15 +228,14 @@ fn rewrite_reorderable_or_regroupable_items(
228228
for (item, list_item) in normalized_items.iter_mut().zip(list_items) {
229229
item.list_item = Some(list_item.clone());
230230
}
231-
match context.config.imports_granularity() {
232-
ImportGranularity::Crate => {
233-
normalized_items = merge_use_trees(normalized_items, SharedPrefix::Crate)
234-
}
231+
normalized_items = match context.config.imports_granularity() {
232+
ImportGranularity::Crate => merge_use_trees(normalized_items, SharedPrefix::Crate),
235233
ImportGranularity::Module => {
236-
normalized_items = merge_use_trees(normalized_items, SharedPrefix::Module)
234+
merge_use_trees(normalized_items, SharedPrefix::Module)
237235
}
238-
ImportGranularity::Preserve => {}
239-
}
236+
ImportGranularity::Item => flatten_use_trees(normalized_items),
237+
ImportGranularity::Preserve => normalized_items,
238+
};
240239

241240
let mut regrouped_items = match context.config.group_imports() {
242241
GroupImportsTactic::Preserve => vec![normalized_items],

Diff for: tests/source/imports_granularity_item.rs

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// rustfmt-imports_granularity: Item
2+
3+
use a::{b, c, d};
4+
use a::{f::g, h::{i, j}};
5+
use a::{l::{self, m, n::o, p::*}};
6+
use a::q::{self};

Diff for: tests/target/imports_granularity_item.rs

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// rustfmt-imports_granularity: Item
2+
3+
use a::b;
4+
use a::c;
5+
use a::d;
6+
use a::f::g;
7+
use a::h::i;
8+
use a::h::j;
9+
use a::l::m;
10+
use a::l::n::o;
11+
use a::l::p::*;
12+
use a::l::{self};
13+
use a::q::{self};

0 commit comments

Comments
 (0)