More principled indentation trimming in fixtures

This commit is contained in:
Aleksey Kladov 2020-06-23 22:27:24 +02:00
parent f2f69e75c8
commit aa69757a01
16 changed files with 540 additions and 557 deletions

View file

@ -128,3 +128,85 @@ pub fn split_delim(haystack: &str, delim: char) -> Option<(&str, &str)> {
let idx = haystack.find(delim)?;
Some((&haystack[..idx], &haystack[idx + delim.len_utf8()..]))
}
pub fn trim_indent(mut text: &str) -> String {
if text.starts_with('\n') {
text = &text[1..];
}
let indent = text
.lines()
.filter(|it| !it.trim().is_empty())
.map(|it| it.len() - it.trim_start().len())
.min()
.unwrap_or(0);
lines_with_ends(text)
.map(
|line| {
if line.len() <= indent {
line.trim_start_matches(' ')
} else {
&line[indent..]
}
},
)
.collect()
}
pub fn lines_with_ends(text: &str) -> LinesWithEnds {
LinesWithEnds { text }
}
pub struct LinesWithEnds<'a> {
text: &'a str,
}
impl<'a> Iterator for LinesWithEnds<'a> {
type Item = &'a str;
fn next(&mut self) -> Option<&'a str> {
if self.text.is_empty() {
return None;
}
let idx = self.text.find('\n').map_or(self.text.len(), |it| it + 1);
let (res, next) = self.text.split_at(idx);
self.text = next;
Some(res)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_trim_indent() {
assert_eq!(trim_indent(""), "");
assert_eq!(
trim_indent(
"
hello
world
"
),
"hello\nworld\n"
);
assert_eq!(
trim_indent(
"
hello
world"
),
"hello\nworld"
);
assert_eq!(trim_indent(" hello\n world\n"), "hello\nworld\n");
assert_eq!(
trim_indent(
"
fn main() {
return 92;
}
"
),
"fn main() {\n return 92;\n}\n"
);
}
}