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?