Skip to content

Conversation

@scampi
Copy link
Contributor

@scampi scampi commented Apr 15, 2019

the items::rewrite_struct_field method was already handling multiline
field names via last_line_width, which was rendered moot by the
previous logic in
vertical::AlignedItem::struct_field_prefix_max_min_width.

Close #2869

@scampi
Copy link
Contributor Author

scampi commented May 6, 2019

@topecongiro Thanks for the comments ;o)
In my point of view I don't think we should try to make this option "smarter" by taking into consideration comments or other things. I believe we should keep the option simple and have its effect obvious: it aligns a struct's fields types, regardless or attributes/comment/... .

@scampi
Copy link
Contributor Author

scampi commented May 6, 2019

Following previous comment, SomeType at https://github.com/rust-lang/rustfmt/pull/3513/files#diff-0a38f958508924d579f0171392aa81bcR41 should be aligned with the rest of the struct's fields I think.

@dcarosone
Copy link
Contributor

dcarosone commented May 29, 2019

I agree about essentially ignoring attributes. It's not likely to be useful to consider them as "group separators" because (for example with serde or elastic or several other crates that implement custom derives) if you have attributes on struct fields you might well have them on all (or at least most) fields. Here's a real-world example:

pub struct Output {
    // things shared / derived
    time: DateTime<Utc>,

    cs_method: Intern<String>,
    cs_uri_stem: Intern<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    cs_uri_query: Option<Intern<String>>,
    #[serde(skip_serializing_if = "Option::is_none")]
    cs_user_agent: Option<Intern<String>>,
    #[serde(skip_serializing_if = "Option::is_none")]
    cs_referer: Option<Intern<String>>,
    #[serde(skip_serializing_if = "Option::is_none")]
    cs_host: Option<Intern<String>>,

    // things from IIS
    #[serde(skip_serializing_if = "Option::is_none")]
    iis_time: Option<DateTime<Utc>>,
    #[serde(skip_serializing_if = "Option::is_none")]
    iis_ip: Option<Ipv4Addr>,
    #[serde(skip_serializing_if = "Option::is_none")]
    iis_port: Option<u16>,
    #[serde(skip_serializing_if = "Option::is_none")]
    iis_username: Option<Intern<String>>,

    .... // many more
}

Comments, especially doc-comments, likewise - if you're documenting your fields, you should document them all.

Blank lines should separate alignment groups. Comments and attributes should be ignored.

@scampi
Copy link
Contributor Author

scampi commented Jun 5, 2019

@topecongiro Are you ok with the comments ? If so, I will fix the alignment when there is a comment #3513 (comment)

@topecongiro
Copy link
Contributor

@scampi Sorry for the late review. IMHO I do not see the benefit of aligning fields when they are not consecutive. Also, it does not make sense to align fields when the comment or attributes between them have multiple lines (FYI gofmt doesn't align fields that are separated by comment or empty lines).

@scampi
Copy link
Contributor Author

scampi commented Jun 7, 2019

@topecongiro Thanks for sharing ;o) If we align fields only when they are together, then there is very little practical use to the config option I think: most of the time, I expect fields to have a doc comment.

The concept of grouping could be handled by a separate config option:

  • group by blank lines
  • group fields up to a maximum field length
  • ...

BTW, this grouping option would fit nicely in the structured configuration you proposed once #3487:

[struct.field]
struct_field_align_threshold = 100

[struct.field.group]
# whether to group by blank lines
blank_lines = "yes"
# whether to group by comments
comment = "yes"
# whether to group by attributes
attribute = "no"

@scampi
Copy link
Contributor Author

scampi commented Jun 7, 2019

Taking a struct from rustfmt codebase:

struct ChainFormatterShared<'a> {
    // The current working set of child items.
    children:         &'a [ChainItem],
    // The current rewrites of items (includes trailing `?`s, but not any way to
    // connect the rewrites together).
    rewrites:         Vec<String>,
    // Whether the chain can fit on one line.
    fits_single_line: bool,
    // The number of children in the chain. This is not equal to `self.children.len()`
    // because `self.children` will change size as we process the chain.
    child_count:      usize,
}

struct ChainFormatterShared<'a> {
    // The current working set of child items.
    children: &'a [ChainItem],
    // The current rewrites of items (includes trailing `?`s, but not any way to
    // connect the rewrites together).
    rewrites: Vec<String>,
    // Whether the chain can fit on one line.
    fits_single_line: bool,
    // The number of children in the chain. This is not equal to `self.children.len()`
    // because `self.children` will change size as we process the chain.
    child_count: usize,
}

I thought as well aligned fields would look strange because of the multiline comments inbetween, but it is more readable when aligned as it looks less packed together. It's a matter of taste.

@topecongiro
Copy link
Contributor

Hmm, looking at your example, I think it's fine to align fields even when there are a multi-line comment or attributes. I personally don't use this feature, so you should have a better idea of what is good or not.

Blank lines should separate alignment groups. Comments and attributes should be ignored.

Sorry that it took a long time to reach the design direction, but could you update this PR according to this comment?

The concept of grouping could be handled by a separate config option:

This is cool, but probably too nitch to provide as an option, I think.

the `items::rewrite_struct_field` method was already handling multiline
field names via `last_line_width`, which was rendered moot by the
previous logic in
`vertical::AlignedItem::struct_field_prefix_max_min_width`.

Close rust-lang#2869
@scampi
Copy link
Contributor Author

scampi commented Sep 28, 2019

@topecongiro sorry for the delay in coming back to this PR. What do you think of the changes?

Copy link
Contributor

@topecongiro topecongiro left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@scampi Well, this is my turn to say sorry about the delay 🙉 The code looks good to me. Thanks!

@topecongiro topecongiro merged commit 5327c36 into rust-lang:master Oct 19, 2019
@topecongiro topecongiro added this to the 1.4.10 milestone Oct 19, 2019
@scampi scampi deleted the issue-2869 branch October 20, 2019 23:28
@scampi
Copy link
Contributor Author

scampi commented Oct 21, 2019

@topecongiro I don't mind ;o) thanks for taking time reviewing this!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

struct_field_align_threshold defeated by serde field atttributes

3 participants