Skip to content

Commit

Permalink
Add an unnest_imports option to break apart nested import groups.
Browse files Browse the repository at this point in the history
  • Loading branch information
goffrie committed Dec 16, 2020
1 parent 81ad114 commit c5f0285
Show file tree
Hide file tree
Showing 6 changed files with 88 additions and 1 deletion.
26 changes: 26 additions & 0 deletions Configurations.md
Original file line number Diff line number Diff line change
Expand Up @@ -2548,6 +2548,32 @@ fn lorem<Ipsum: Dolor+Sit=Amet>() {
}
```

## `unnest_imports`

Break apart nested import groups into separate `use` statements.
When used with `merge_imports`, imports will be merged together by module but
not merge into a single tree.

- **Default value**: `false`
- **Possible values**: `true`, `false`
- **Stable**: No

#### `false` (default):

```rust
use foo::{a::b, c};
use foo::{d::{e, f}, g::{h, i}};
```

#### `true`:

```rust
use foo::a::b;
use foo::c;
use foo::d::{e, f};
use foo::g::{h, i};
```

## `unstable_features`

Enable unstable features on stable and beta channels (unstable features are available by default on nightly).
Expand Down
2 changes: 2 additions & 0 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ create_config! {
imports_indent: IndentStyle, IndentStyle::Block, false, "Indent of imports";
imports_layout: ListTactic, ListTactic::Mixed, false, "Item layout inside a import block";
merge_imports: bool, false, false, "Merge imports";
unnest_imports: bool, false, false, "Break apart nested import groups";
group_imports: GroupImportsTactic, GroupImportsTactic::Preserve, false,
"Controls the strategy for how imports are grouped together";

Expand Down Expand Up @@ -596,6 +597,7 @@ where_single_line = false
imports_indent = "Block"
imports_layout = "Mixed"
merge_imports = false
unnest_imports = false
group_imports = "Preserve"
reorder_imports = true
reorder_modules = true
Expand Down
38 changes: 38 additions & 0 deletions src/formatting/imports.rs
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,44 @@ pub(crate) fn merge_use_trees(use_trees: Vec<UseTree>) -> Vec<UseTree> {
result
}

pub(crate) fn unnest_use_trees(mut use_trees: Vec<UseTree>) -> Vec<UseTree> {
let mut result = Vec::with_capacity(use_trees.len());
while let Some(mut use_tree) = use_trees.pop() {
if !use_tree.has_comment() && use_tree.attrs.is_none() {
if let Some((UseSegment::List(list), ref prefix)) = use_tree.path.split_last_mut() {
let span = use_tree.span;
let visibility = &use_tree.visibility;
list.retain(|nested_use_tree| {
if matches!(
nested_use_tree.path[..],
[UseSegment::Ident(..)] | [UseSegment::Slf(..)] | [UseSegment::Glob]
) {
return true;
}
// nested item detected; flatten once, but process it again
// in case it has more nesting
use_trees.push(UseTree {
path: prefix
.iter()
.cloned()
.chain(nested_use_tree.path.iter().cloned())
.collect(),
span,
list_item: None,
visibility: visibility.clone(),
attrs: None,
});
// remove this item
false
});
use_tree = use_tree.normalize();
}
}
result.push(use_tree);
}
result
}

impl fmt::Debug for UseTree {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Display::fmt(self, f)
Expand Down
5 changes: 4 additions & 1 deletion src/formatting/reorder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use crate::config::{Config, GroupImportsTactic};
use crate::formatting::imports::UseSegment;
use crate::formatting::modules::{get_mod_inner_attrs, FileModMap};
use crate::formatting::{
imports::{merge_use_trees, UseTree},
imports::{merge_use_trees, unnest_use_trees, UseTree},
items::{is_mod_decl, rewrite_extern_crate, rewrite_mod},
lists::{itemize_list, write_list, ListFormatting, ListItem},
rewrite::RewriteContext,
Expand Down Expand Up @@ -229,6 +229,9 @@ fn rewrite_reorderable_or_regroupable_items(
if context.config.merge_imports() {
normalized_items = merge_use_trees(normalized_items);
}
if context.config.unnest_imports() {
normalized_items = unnest_use_trees(normalized_items);
}

let mut regrouped_items = match context.config.group_imports() {
GroupImportsTactic::Preserve => vec![normalized_items],
Expand Down
6 changes: 6 additions & 0 deletions tests/source/unnest_imports.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// rustfmt-unnest_imports: true

use a::{b::c, d::e};
use a::{f, g::{h, i}};
use a::{f::{self, g::{self, h}, i}, j::{k::l, m}};
pub use a::{n::o, p};
12 changes: 12 additions & 0 deletions tests/target/unnest_imports.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// rustfmt-unnest_imports: true

use a::b::c;
use a::d::e;
use a::f;
use a::f::g::{self, h};
use a::f::{self, i};
use a::g::{h, i};
use a::j::k::l;
use a::j::m;
pub use a::n::o;
pub use a::p;

0 comments on commit c5f0285

Please sign in to comment.