Skip to content

Commit

Permalink
Add ExternalCrate import grouping style
Browse files Browse the repository at this point in the history
This creates two groups:

1. `std`, `core`, `alloc` and external crates,
2. `self`, `super` and `crate` imports.
  • Loading branch information
shepmaster committed Mar 26, 2023
1 parent 34f9ca2 commit b036bb4
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 3 deletions.
22 changes: 21 additions & 1 deletion Configurations.md
Original file line number Diff line number Diff line change
Expand Up @@ -2229,7 +2229,7 @@ Controls the strategy for how consecutive imports are grouped together.
Controls the strategy for grouping sets of consecutive imports. Imports may contain newlines between imports and still be grouped together as a single set, but other statements between imports will result in different grouping sets.

- **Default value**: `Preserve`
- **Possible values**: `Preserve`, `StdExternalCrate`, `One`
- **Possible values**: `Preserve`, `StdExternalCrate`, `ExternalCrate`, `One`
- **Stable**: No (tracking issue: [#5083](https://github.com/rust-lang/rustfmt/issues/5083))

Each set of imports (one or more `use` statements, optionally separated by newlines) will be formatted independently. Other statements such as `mod ...` or `extern crate ...` will cause imports to not be grouped together.
Expand Down Expand Up @@ -2277,6 +2277,26 @@ use super::update::convert_publish_payload;
use crate::models::Event;
```

#### `ExternalCrate`:

Discard existing import groups, and create two groups for:
1. `std`, `core`, `alloc` and external crates,
2. `self`, `super` and `crate` imports.

```rust
use alloc::alloc::Layout;
use broker::database::PooledConnection;
use chrono::Utc;
use core::f32;
use juniper::{FieldError, FieldResult};
use std::sync::Arc;
use uuid::Uuid;

use super::schema::{Context, Payload};
use super::update::convert_publish_payload;
use crate::models::Event;
```

#### `One`:

Discard existing import groups, and create a single group for everything
Expand Down
4 changes: 4 additions & 0 deletions src/config/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,10 @@ pub enum GroupImportsTactic {
/// 2. other imports
/// 3. `self` / `crate` / `super` imports
StdExternalCrate,
/// Discard existing groups, and create new groups for
/// 1. `std` / `core` / `alloc` / other imports
/// 2. `self` / `crate` / `super` imports
ExternalCrate,
/// Discard existing groups, and create a single group for everything
One,
}
Expand Down
31 changes: 29 additions & 2 deletions src/reorder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,10 @@ fn rewrite_reorderable_or_regroupable_items(
GroupImportsTactic::Preserve | GroupImportsTactic::One => {
vec![normalized_items]
}
GroupImportsTactic::StdExternalCrate => group_imports(normalized_items),
GroupImportsTactic::StdExternalCrate => {
group_imports_std_external_crate(normalized_items)
}
GroupImportsTactic::ExternalCrate => group_imports_external_crate(normalized_items),
};

if context.config.reorder_imports() {
Expand Down Expand Up @@ -172,7 +175,7 @@ fn contains_macro_use_attr(item: &ast::Item) -> bool {

/// Divides imports into three groups, corresponding to standard, external
/// and local imports. Sorts each subgroup.
fn group_imports(uts: Vec<UseTree>) -> Vec<Vec<UseTree>> {
fn group_imports_std_external_crate(uts: Vec<UseTree>) -> Vec<Vec<UseTree>> {
let mut std_imports = Vec::new();
let mut external_imports = Vec::new();
let mut local_imports = Vec::new();
Expand All @@ -198,6 +201,30 @@ fn group_imports(uts: Vec<UseTree>) -> Vec<Vec<UseTree>> {
vec![std_imports, external_imports, local_imports]
}

/// Divides imports into two groups, corresponding to external crates
/// and local imports. Sorts each subgroup.
fn group_imports_external_crate(uts: Vec<UseTree>) -> Vec<Vec<UseTree>> {
let mut external_imports = Vec::new();
let mut local_imports = Vec::new();

for ut in uts.into_iter() {
if ut.path.is_empty() {
external_imports.push(ut);
continue;
}
match &ut.path[0].kind {
UseSegmentKind::Ident(..) => external_imports.push(ut),
UseSegmentKind::Slf(_) | UseSegmentKind::Super(_) | UseSegmentKind::Crate(_) => {
local_imports.push(ut)
}
// These are probably illegal here
UseSegmentKind::Glob | UseSegmentKind::List(_) => external_imports.push(ut),
}
}

vec![external_imports, local_imports]
}

/// A simplified version of `ast::ItemKind`.
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
enum ReorderableItemKind {
Expand Down
15 changes: 15 additions & 0 deletions tests/source/configs/group_imports/ExternalCrate.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// rustfmt-group_imports: ExternalCrate
use chrono::Utc;
use super::update::convert_publish_payload;

use juniper::{FieldError, FieldResult};
use uuid::Uuid;
use alloc::alloc::Layout;

use std::sync::Arc;

use broker::database::PooledConnection;

use super::schema::{Context, Payload};
use core::f32;
use crate::models::Event;
12 changes: 12 additions & 0 deletions tests/target/configs/group_imports/ExternalCrate.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// rustfmt-group_imports: ExternalCrate
use alloc::alloc::Layout;
use broker::database::PooledConnection;
use chrono::Utc;
use core::f32;
use juniper::{FieldError, FieldResult};
use std::sync::Arc;
use uuid::Uuid;

use super::schema::{Context, Payload};
use super::update::convert_publish_payload;
use crate::models::Event;

0 comments on commit b036bb4

Please sign in to comment.