Skip to content

Commit 7186375

Browse files
goffriecalebcartwright
authored andcommitted
Rename merge_imports to imports_granularity and add a Module option.
This renames the existing `true`/`false` options to `Crate`/`Never`, then adds a new `Module` option which causes imports to be grouped together by their originating module.
1 parent 216a643 commit 7186375

18 files changed

+291
-52
lines changed

Diff for: Configurations.md

+45-2
Original file line numberDiff line numberDiff line change
@@ -1615,13 +1615,56 @@ pub enum Foo {}
16151615
pub enum Foo {}
16161616
```
16171617

1618+
## `imports_granularity`
1619+
1620+
Merge together related imports based on their paths.
1621+
1622+
- **Default value**: `Preserve`
1623+
- **Possible values**: `Preserve`, `Crate`, `Module`
1624+
- **Stable**: No
1625+
1626+
#### `Preserve` (default):
1627+
1628+
Do not perform any merging and preserve the original structure written by the developer.
1629+
1630+
```rust
1631+
use foo::b;
1632+
use foo::b::{f, g};
1633+
use foo::{a, c, d::e};
1634+
use qux::{h, i};
1635+
```
1636+
1637+
#### `Crate`:
1638+
1639+
Merge imports from the same crate into a single `use` statement. Conversely, imports from different crates are split into separate statements.
1640+
1641+
```rust
1642+
use foo::{
1643+
a, b,
1644+
b::{f, g},
1645+
c,
1646+
d::e,
1647+
};
1648+
use qux::{h, i};
1649+
```
1650+
1651+
#### `Module`:
1652+
1653+
Merge imports from the same module into a single `use` statement. Conversely, imports from different modules are split into separate statements.
1654+
1655+
```rust
1656+
use foo::b::{f, g};
1657+
use foo::d::e;
1658+
use foo::{a, b, c};
1659+
use qux::{h, i};
1660+
```
1661+
16181662
## `merge_imports`
16191663

1620-
Merge multiple imports into a single nested import.
1664+
This option is deprecated. Use `imports_granularity = "Crate"` instead.
16211665

16221666
- **Default value**: `false`
16231667
- **Possible values**: `true`, `false`
1624-
- **Stable**: No (tracking issue: #3362)
16251668

16261669
#### `false` (default):
16271670

Diff for: src/config/config_type.rs

+21-2
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ macro_rules! create_config {
9797
match stringify!($i) {
9898
"max_width" | "use_small_heuristics" => self.0.set_heuristics(),
9999
"license_template_path" => self.0.set_license_template(),
100+
"merge_imports" => self.0.set_merge_imports(),
100101
&_ => (),
101102
}
102103
}
@@ -156,6 +157,7 @@ macro_rules! create_config {
156157
self.set_heuristics();
157158
self.set_license_template();
158159
self.set_ignore(dir);
160+
self.set_merge_imports();
159161
self
160162
}
161163

@@ -230,14 +232,15 @@ macro_rules! create_config {
230232
match key {
231233
"max_width" | "use_small_heuristics" => self.set_heuristics(),
232234
"license_template_path" => self.set_license_template(),
235+
"merge_imports" => self.set_merge_imports(),
233236
&_ => (),
234237
}
235238
}
236239

237240
#[allow(unreachable_pub)]
238241
pub fn is_hidden_option(name: &str) -> bool {
239-
const HIDE_OPTIONS: [&str; 4] =
240-
["verbose", "verbose_diff", "file_lines", "width_heuristics"];
242+
const HIDE_OPTIONS: [&str; 5] =
243+
["verbose", "verbose_diff", "file_lines", "width_heuristics", "merge_imports"];
241244
HIDE_OPTIONS.contains(&name)
242245
}
243246

@@ -309,6 +312,22 @@ macro_rules! create_config {
309312
self.ignore.2.add_prefix(dir);
310313
}
311314

315+
fn set_merge_imports(&mut self) {
316+
if self.was_set().merge_imports() {
317+
eprintln!(
318+
"Warning: the `merge_imports` option is deprecated. \
319+
Use `imports_granularity=Crate` instead"
320+
);
321+
if !self.was_set().imports_granularity() {
322+
self.imports_granularity.2 = if self.merge_imports() {
323+
ImportGranularity::Crate
324+
} else {
325+
ImportGranularity::Preserve
326+
};
327+
}
328+
}
329+
}
330+
312331
#[allow(unreachable_pub)]
313332
/// Returns `true` if the config key was explicitly set and is the default value.
314333
pub fn is_default(&self, key: &str) -> bool {

Diff for: src/config/mod.rs

+58-2
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,11 @@ create_config! {
6464
// Imports
6565
imports_indent: IndentStyle, IndentStyle::Block, false, "Indent of imports";
6666
imports_layout: ListTactic, ListTactic::Mixed, false, "Item layout inside a import block";
67-
merge_imports: bool, false, false, "Merge imports";
67+
imports_granularity: ImportGranularity, ImportGranularity::Preserve, false,
68+
"Merge or split imports to the provided granularity";
6869
group_imports: GroupImportsTactic, GroupImportsTactic::Preserve, false,
6970
"Controls the strategy for how imports are grouped together";
71+
merge_imports: bool, false, false, "(deprecated: use imports_granularity instead)";
7072

7173
// Ordering
7274
reorder_imports: bool, true, true, "Reorder import and extern crate statements alphabetically";
@@ -174,6 +176,7 @@ impl PartialConfig {
174176
cloned.verbose = None;
175177
cloned.width_heuristics = None;
176178
cloned.print_misformatted_file_names = None;
179+
cloned.merge_imports = None;
177180

178181
::toml::to_string(&cloned).map_err(ToTomlError)
179182
}
@@ -407,6 +410,10 @@ mod test {
407410
via the --file-lines option";
408411
width_heuristics: WidthHeuristics, WidthHeuristics::scaled(100), false,
409412
"'small' heuristic values";
413+
// merge_imports deprecation
414+
imports_granularity: ImportGranularity, ImportGranularity::Preserve, false,
415+
"Merge imports";
416+
merge_imports: bool, false, false, "(deprecated: use imports_granularity instead)";
410417

411418
// Options that are used by the tests
412419
stable_option: bool, false, true, "A stable option";
@@ -529,7 +536,7 @@ fn_single_line = false
529536
where_single_line = false
530537
imports_indent = "Block"
531538
imports_layout = "Mixed"
532-
merge_imports = false
539+
imports_granularity = "Preserve"
533540
group_imports = "Preserve"
534541
reorder_imports = true
535542
reorder_modules = true
@@ -615,4 +622,53 @@ make_backup = false
615622
// assert_eq!(config.unstable_features(), true);
616623
// ::std::env::set_var("CFG_RELEASE_CHANNEL", v);
617624
// }
625+
626+
#[cfg(test)]
627+
mod deprecated_option_merge_imports {
628+
use super::*;
629+
630+
#[test]
631+
fn test_old_option_set() {
632+
let toml = r#"
633+
unstable_features = true
634+
merge_imports = true
635+
"#;
636+
let config = Config::from_toml(toml, Path::new("")).unwrap();
637+
assert_eq!(config.imports_granularity(), ImportGranularity::Crate);
638+
}
639+
640+
#[test]
641+
fn test_both_set() {
642+
let toml = r#"
643+
unstable_features = true
644+
merge_imports = true
645+
imports_granularity = "Preserve"
646+
"#;
647+
let config = Config::from_toml(toml, Path::new("")).unwrap();
648+
assert_eq!(config.imports_granularity(), ImportGranularity::Preserve);
649+
}
650+
651+
#[test]
652+
fn test_new_overridden() {
653+
let toml = r#"
654+
unstable_features = true
655+
merge_imports = true
656+
"#;
657+
let mut config = Config::from_toml(toml, Path::new("")).unwrap();
658+
config.override_value("imports_granularity", "Preserve");
659+
assert_eq!(config.imports_granularity(), ImportGranularity::Preserve);
660+
}
661+
662+
#[test]
663+
fn test_old_overridden() {
664+
let toml = r#"
665+
unstable_features = true
666+
imports_granularity = "Module"
667+
"#;
668+
let mut config = Config::from_toml(toml, Path::new("")).unwrap();
669+
config.override_value("merge_imports", "true");
670+
// no effect: the new option always takes precedence
671+
assert_eq!(config.imports_granularity(), ImportGranularity::Module);
672+
}
673+
}
618674
}

Diff for: src/config/options.rs

+13-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use std::collections::{hash_set, HashSet};
22
use std::fmt;
33
use std::path::{Path, PathBuf};
4+
use std::str::FromStr;
45

56
use itertools::Itertools;
67
use rustfmt_config_proc_macro::config_type;
@@ -111,6 +112,17 @@ pub enum GroupImportsTactic {
111112
StdExternalCrate,
112113
}
113114

115+
#[config_type]
116+
/// How to merge imports.
117+
pub enum ImportGranularity {
118+
/// Do not merge imports.
119+
Preserve,
120+
/// Use one `use` statement per crate.
121+
Crate,
122+
/// Use one `use` statement per module.
123+
Module,
124+
}
125+
114126
#[config_type]
115127
pub enum ReportTactic {
116128
Always,
@@ -362,7 +374,7 @@ impl IgnoreList {
362374
}
363375
}
364376

365-
impl ::std::str::FromStr for IgnoreList {
377+
impl FromStr for IgnoreList {
366378
type Err = &'static str;
367379

368380
fn from_str(_: &str) -> Result<Self, Self::Err> {

0 commit comments

Comments
 (0)