Description
Currently code passing a multiline string argument to a function will be reformatted to a multiline call no matter whether it needs it or not. Example using unindent
crate:
fn main() {
assert_eq!(code, unindent(r#"
def hello():
print("Hello, world!")
hello()
"#));
}
->
fn main() {
assert_eq!(
code,
unindent(
r#"
def hello():
print("Hello, world!")
hello()
"#
)
);
}
You can see how it becomes hard to track the beginning / end of the string literal and surrounding call due to extra line breaks with varying indentation.
Same happens when using an indoc!
macro instead:
fn main() {
assert_eq!(code, indoc!(r#"
def hello():
print("Hello, world!")
hello()
"#));
}
->
fn main() {
assert_eq!(
code,
indoc!(
r#"
def hello():
print("Hello, world!")
hello()
"#
)
);
}
Reformatting that takes place in these examples kind of defeats the purpose of using indoc!
in the first place which is to prettify multiline string literals in code while preserving indentation.
I think it would be possible to special-case indoc!
as Rustfmt already does for few other well-known macros, but maybe instead it would be better to fix this issue in general? For example, I like what happens to "multiline" struct literals in same argument position much more:
fn main() {
assert_eq!(s, wrap(A {
x: 10,
y: 20,
z: 30,
}));
}
->
fn main() {
assert_eq!(
s,
wrap(A {
x: 10,
y: 20,
z: 30,
})
);
}
I understand that their handling is different, as structs can be also reformatted to fit on same line, but still I wonder if it would be possible / make sense to apply same logic to strings and keep beginning and end quotes near their corresponding parentheses of the surrounding call?
cc @dtolnay as author of mentioned crates