Skip to content

Commit 4f4acf7

Browse files
committed
Decouple reordering and grouping
1 parent 364981f commit 4f4acf7

File tree

3 files changed

+42
-30
lines changed

3 files changed

+42
-30
lines changed

src/formatting/reorder.rs

+38-20
Original file line numberDiff line numberDiff line change
@@ -193,9 +193,10 @@ fn rewrite_reorderable_item(
193193
}
194194
}
195195

196-
/// Rewrite a list of items with reordering. Every item in `items` must have
197-
/// the same `ast::ItemKind`.
198-
fn rewrite_reorderable_items(
196+
/// Rewrite a list of items with reordering and/or regrouping. Every item
197+
/// in `items` must have the same `ast::ItemKind`. Whether reordering, regrouping,
198+
/// or both ore done is determined from the `context`.
199+
fn rewrite_reorderable_or_regroupable_items(
199200
context: &RewriteContext<'_>,
200201
reorderable_items: &[&ast::Item],
201202
shape: Shape,
@@ -229,16 +230,20 @@ fn rewrite_reorderable_items(
229230
normalized_items = merge_use_trees(normalized_items);
230231
}
231232

232-
let reordered_imports = if context.config.group_imports() != GroupImportsTactic::None {
233-
group_and_sort_imports(normalized_items)
233+
let mut regrouped_items = if context.config.group_imports() != GroupImportsTactic::None
234+
{
235+
group_imports(normalized_items)
234236
} else {
235-
normalized_items.sort();
236237
vec![normalized_items]
237238
};
238239

240+
if context.config.reorder_imports() {
241+
regrouped_items.iter_mut().for_each(|items| items.sort())
242+
}
243+
239244
// 4 = "use ", 1 = ";"
240245
let nested_shape = shape.offset_left(4)?.sub_width(1)?;
241-
let item_vec: Vec<_> = reordered_imports
246+
let item_vec: Vec<_> = regrouped_items
242247
.into_iter()
243248
.filter(|use_group| !use_group.is_empty())
244249
.map(|use_group| {
@@ -284,7 +289,7 @@ fn contains_macro_use_attr(attrs: &[ast::Attribute]) -> bool {
284289

285290
/// Divides imports into three groups, corresponding to standard, external
286291
/// and local imports. Sorts each subgroup.
287-
fn group_and_sort_imports(uts: Vec<UseTree>) -> Vec<Vec<UseTree>> {
292+
fn group_imports(uts: Vec<UseTree>) -> Vec<Vec<UseTree>> {
288293
let mut std_imports = Vec::new();
289294
let mut external_imports = Vec::new();
290295
let mut local_imports = Vec::new();
@@ -307,10 +312,6 @@ fn group_and_sort_imports(uts: Vec<UseTree>) -> Vec<Vec<UseTree>> {
307312
}
308313
}
309314

310-
std_imports.sort();
311-
external_imports.sort();
312-
local_imports.sort();
313-
314315
vec![std_imports, external_imports, local_imports]
315316
}
316317

@@ -357,6 +358,15 @@ impl ReorderableItemKind {
357358
}
358359
}
359360

361+
fn is_regroupable(self, config: &Config) -> bool {
362+
match self {
363+
ReorderableItemKind::ExternCrate
364+
| ReorderableItemKind::Mod
365+
| ReorderableItemKind::Other => false,
366+
ReorderableItemKind::Use => config.group_imports() != GroupImportsTactic::None,
367+
}
368+
}
369+
360370
fn in_group(self, config: &Config) -> bool {
361371
match self {
362372
ReorderableItemKind::ExternCrate | ReorderableItemKind::Mod => true,
@@ -367,10 +377,10 @@ impl ReorderableItemKind {
367377
}
368378

369379
impl<'b, 'a: 'b> FmtVisitor<'a> {
370-
/// Format items with the same item kind and reorder them. If `in_group` is
371-
/// `true`, then the items separated by an empty line will not be reordered
372-
/// together.
373-
fn walk_reorderable_items(
380+
/// Format items with the same item kind and reorder them, regroup them, or
381+
/// both. If `in_group` is `true`, then the items separated by an empty line
382+
/// will not be reordered together.
383+
fn walk_reorderable_or_regroupable_items(
374384
&mut self,
375385
items: &[&ast::Item],
376386
item_kind: ReorderableItemKind,
@@ -400,7 +410,12 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
400410
let lo = items.first().unwrap().span().lo();
401411
let hi = items.last().unwrap().span().hi();
402412
let span = mk_sp(lo, hi);
403-
let rw = rewrite_reorderable_items(&self.get_context(), items, self.shape(), span);
413+
let rw = rewrite_reorderable_or_regroupable_items(
414+
&self.get_context(),
415+
items,
416+
self.shape(),
417+
span,
418+
);
404419
self.push_rewrite(span, rw);
405420
} else {
406421
for item in items {
@@ -419,9 +434,12 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
419434
// subsequent items that have the same item kind to be reordered within
420435
// `walk_reorderable_items`. Otherwise, just format the next item for output.
421436
let item_kind = ReorderableItemKind::from(items[0], self.file_mod_map);
422-
if item_kind.is_reorderable(self.config) {
423-
let visited_items_num =
424-
self.walk_reorderable_items(items, item_kind, item_kind.in_group(self.config));
437+
if item_kind.is_reorderable(self.config) || item_kind.is_regroupable(self.config) {
438+
let visited_items_num = self.walk_reorderable_or_regroupable_items(
439+
items,
440+
item_kind,
441+
item_kind.in_group(self.config),
442+
);
425443
let (_, rest) = items.split_at(visited_items_num);
426444
items = rest;
427445
} else {

tests/source/group_imports-no_reorder.rs

-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
// rustfmt-group_imports: StdExternalCrate
22
// rustfmt-reorder_imports: false
33

4-
// group_imports has no effect when reorder_imports is disabled.
5-
64
use chrono::Utc;
75
use super::update::convert_publish_payload;
86

+4-8
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,15 @@
11
// rustfmt-group_imports: StdExternalCrate
22
// rustfmt-reorder_imports: false
33

4-
// group_imports has no effect when reorder_imports is disabled.
4+
use alloc::alloc::Layout;
5+
use std::sync::Arc;
6+
use core::f32;
57

68
use chrono::Utc;
7-
use super::update::convert_publish_payload;
8-
99
use juniper::{FieldError, FieldResult};
1010
use uuid::Uuid;
11-
use alloc::alloc::Layout;
12-
13-
use std::sync::Arc;
14-
1511
use broker::database::PooledConnection;
1612

13+
use super::update::convert_publish_payload;
1714
use super::schema::{Context, Payload};
18-
use core::f32;
1915
use crate::models::Event;

0 commit comments

Comments
 (0)