mirror of
https://github.com/askama-rs/askama.git
synced 2025-09-27 13:00:57 +00:00
Track first line across calls and add tests
Fix logic issue where `self.first` was not tracked across calls, causing incorrect indentation. Replaced `idx` with `is_first_line` flag. Added `test_indent_chunked` to verify correct behavior.
This commit is contained in:
parent
6653662d9e
commit
77b0763679
@ -108,6 +108,7 @@ struct IndentWriter<'a, W> {
|
||||
first: bool,
|
||||
blank: bool,
|
||||
is_new_line: bool,
|
||||
is_first_line: bool,
|
||||
}
|
||||
|
||||
impl<'a, W: fmt::Write> IndentWriter<'a, W> {
|
||||
@ -118,6 +119,7 @@ impl<'a, W: fmt::Write> IndentWriter<'a, W> {
|
||||
first,
|
||||
blank,
|
||||
is_new_line: true,
|
||||
is_first_line: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -128,12 +130,19 @@ impl<W: fmt::Write> fmt::Write for IndentWriter<'_, W> {
|
||||
return self.dest.write_str(s);
|
||||
}
|
||||
|
||||
for (idx, line) in s.split_inclusive('\n').enumerate() {
|
||||
if (self.first || idx > 0 || !self.is_new_line)
|
||||
&& (self.blank || !matches!(line, "\n" | "\r\n"))
|
||||
{
|
||||
for line in s.split_inclusive('\n') {
|
||||
if self.is_new_line {
|
||||
if self.is_first_line {
|
||||
if self.first && (self.blank || !matches!(line, "\n" | "\r\n")) {
|
||||
self.dest.write_str(self.indent)?;
|
||||
}
|
||||
self.is_first_line = false;
|
||||
} else {
|
||||
if self.blank || !matches!(line, "\n" | "\r\n") {
|
||||
self.dest.write_str(self.indent)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
self.dest.write_str(line)?;
|
||||
self.is_new_line = line.ends_with('\n');
|
||||
}
|
||||
@ -309,6 +318,65 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_indent_chunked() {
|
||||
#[derive(Clone, Copy)]
|
||||
struct Chunked<'a>(&'a str);
|
||||
|
||||
impl<'a> fmt::Display for Chunked<'a> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
for chunk in self.0.chars() {
|
||||
write!(f, "{}", chunk)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
assert_eq!(
|
||||
indent(Chunked("hello"), 2, false, false).unwrap().to_string(),
|
||||
"hello"
|
||||
);
|
||||
assert_eq!(
|
||||
indent(Chunked("hello\n"), 2, false, false).unwrap().to_string(),
|
||||
"hello\n"
|
||||
);
|
||||
assert_eq!(
|
||||
indent(Chunked("hello\nfoo"), 2, false, false).unwrap().to_string(),
|
||||
"hello\n foo"
|
||||
);
|
||||
assert_eq!(
|
||||
indent(Chunked("hello\nfoo\n bar"), 4, false, false)
|
||||
.unwrap()
|
||||
.to_string(),
|
||||
"hello\n foo\n bar"
|
||||
);
|
||||
assert_eq!(
|
||||
indent(Chunked("hello"), 267_332_238_858, false, false)
|
||||
.unwrap()
|
||||
.to_string(),
|
||||
"hello"
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
indent(Chunked("hello\n\n bar"), 4, false, false)
|
||||
.unwrap()
|
||||
.to_string(),
|
||||
"hello\n\n bar"
|
||||
);
|
||||
assert_eq!(
|
||||
indent(Chunked("hello\n\n bar"), 4, false, true).unwrap().to_string(),
|
||||
"hello\n \n bar"
|
||||
);
|
||||
assert_eq!(
|
||||
indent(Chunked("hello\n\n bar"), 4, true, false).unwrap().to_string(),
|
||||
" hello\n\n bar"
|
||||
);
|
||||
assert_eq!(
|
||||
indent(Chunked("hello\n\n bar"), 4, true, true).unwrap().to_string(),
|
||||
" hello\n \n bar"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[allow(clippy::arc_with_non_send_sync)] // it's only a test, it does not have to make sense
|
||||
#[allow(clippy::type_complexity)] // it's only a test, it does not have to be pretty
|
||||
|
Loading…
x
Reference in New Issue
Block a user