Skip to content

imports_granularity: implement One/Single variant #4669

Closed
@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

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions