This is an automated archive made by the Lemmit Bot.
The original was posted on /r/rust by /u/Shivalicious on 2023-08-10 22:57:16.
I have a file on disk. I want to find a particular line (whitespace & case insignificant), skip blank lines after it, skip one non-blank line, skip blank lines, and get the first non-blank line. The file looks like this:
something
something else
things
some pattern
ignore this line
return this line
other stuff
`I want `return this line`. I’ve implemented two ways of parsing it so far. With a loop:`rust
let file = File::open(text\_file)?;
let mut reader = BufReader::new(file);
let mut buf = String::new();
let mut expecting\_1 = false;
let mut expecting\_2 = false;
while reader.read\_line(&mut buf)? != 0 {
buf = buf.trim().to\_string();
if buf.is_empty() {
continue;
}
if expecting_2 {
return Ok(Some(buf));
} else if expecting_1 {
expecting_2 = true;
} else if buf.to_ascii_lowercase() == "some pattern" {
expecting_1 = true;
}
buf.clear();
}
Ok(None)
`And by abusing iterators:`rust
let file = File::open(text\_file)?;
let reader = BufReader::new(file);
let amount = reader
.lines()
.map\_while(|l| l.ok().map(|l| l.trim().to\_owned()))
.skip\_while(|l| l.to\_ascii\_lowercase() != "some pattern")
.skip(1)
.skip\_while(|l| l.is\_empty())
.skip(1)
.find(|l| !l.is\_empty());
Ok(amount)
Both work—I haven’t tried very hard to shorten them—but they seem inelegant in concept. Is there a better way?