Fix multiline string formatting

This change adds the proper indentation when formatting multiline
strings to not end up with invalid code. This also make sure that
multiline strings are always formatted using multiple lines, regardless
of the string literal itself contains a newline.
This commit is contained in:
raleng 2022-08-23 12:45:30 +02:00
parent 04a0a71e83
commit 4991adb05b
No known key found for this signature in database
GPG key ID: A7DBF700E0E77020

View file

@ -419,7 +419,15 @@ fn format_str_segment<'a, 'buf>(seg: &StrSegment<'a>, buf: &mut Buf<'buf>, inden
match seg {
Plaintext(string) => {
buf.push_str_allow_spaces(string);
// Lines in block strings will end with Plaintext ending in "\n" to indicate
// a line break in the input string
match string.strip_suffix('\n') {
Some(string_without_newline) => {
buf.push_str_allow_spaces(string_without_newline);
buf.newline();
}
None => buf.push_str_allow_spaces(string),
}
}
Unicode(loc_str) => {
buf.push_str("\\u(");
@ -501,36 +509,19 @@ pub fn fmt_str_literal<'buf>(buf: &mut Buf<'buf>, literal: StrLiteral, indent: u
}
}
Block(lines) => {
// Block strings will always be formatted with """ on new lines
buf.push_str("\"\"");
buf.newline();
for segments in lines.iter() {
for seg in segments.iter() {
buf.indent(indent);
format_str_segment(seg, buf, indent);
}
if lines.len() > 1 {
// Since we have multiple lines, format this with
// the `"""` symbols on their own lines, and the
buf.newline();
for segments in lines.iter() {
for seg in segments.iter() {
format_str_segment(seg, buf, indent);
}
buf.newline();
}
} else {
// This is a single-line block string, for example:
//
// """Whee, "quotes" inside quotes!"""
// This loop will run either 0 or 1 times.
for segments in lines.iter() {
for seg in segments.iter() {
format_str_segment(seg, buf, indent);
}
// Don't print a newline here, because we either
// just printed 1 or 0 lines.
}
}
buf.indent(indent);
buf.push_str("\"\"");
}
}