Skip to content

imports_granularity: implement One/Single variant #4669

@calebcartwright

Description

@calebcartwright

Add a new variant and associated formatting to imports_granularity that reformats all imports into a single use statement. The variant name should be One or Single, with One being the leading contender (refer here for One and here for Single for respective community votes/feedback)

use {
    futures::{
        ready,
        stream::{Stream, StreamExt},
    },
    std::pin::{Pin, Unpin},
};

Background

imports_granularity is a configuration option that allows users to control the granularity of their use declarations (https://github.com/rust-lang/rustfmt/blob/master/Configurations.md#imports_granularity)

By default rustfmt will not modify the granularity and will preserve the developers original structure, but the imports_granularity option provides several different variants that users can leverage to instruct rustfmt to reformat their use statements with a specific level of granularity.

Several different styles/granularity levels have been identified (summarized here, and already implemented, with the exception of the one/single granularity variant.

Implementation

There will be 3 high level tasks required here

  • Updating the configuration option information
  • Updating the imports merging logic to support the new granularity style
  • Adding tests

For the configuration side:

For implementation, refer to relevant sections in src/formatting/imports.rs and src/formatting/reorder.rs, some suggested starting points:

pub(crate) enum SharedPrefix {
Crate,
Module,
}

fn share_prefix(&self, other: &UseTree, shared_prefix: SharedPrefix) -> bool {
if self.path.is_empty()
|| other.path.is_empty()
|| self.attrs.is_some()
|| !self.same_visibility(other)
{
false
} else {
match shared_prefix {
SharedPrefix::Crate => self.path[0] == other.path[0],
SharedPrefix::Module => {
self.path[..self.path.len() - 1] == other.path[..other.path.len() - 1]
}
}
}
}

normalized_items = match context.config.imports_granularity() {
ImportGranularity::Crate => merge_use_trees(normalized_items, SharedPrefix::Crate),
ImportGranularity::Module => {
merge_use_trees(normalized_items, SharedPrefix::Module)
}
ImportGranularity::Item => flatten_use_trees(normalized_items),
ImportGranularity::Preserve => normalized_items,
};

For tests (more information on writing tests here):
Some unit tests for the other variants can be found here
https://github.com/rust-lang/rustfmt/blob/master/src/formatting/imports.rs#L1032-L1087

Additional files for the system/idempotence tests can be found under tests/{src,target}/imports_granularity_{crate,item,module}.rs for reference

Metadata

Metadata

Assignees

No one assigned

    Labels

    1x-backport:completedA-importsArea: imports, e.g. `use` syntaxC-feature-requestCategory: a feature request (not decided/implemented)E-help-wantedCall for participation: help is requested to fix this issuegood first issueIssues up for grabs, also good candidates for new rustfmt contributors

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions