advent_of_code_2023_in_rust/src/parsing_utils.rs
BoolPurist cb7e8465a2 Implemented input as direct value or as file input
Implemented parsing for day5
2024-08-16 16:36:56 +02:00

56 lines
1.4 KiB
Rust

pub fn blocks_of_lines_seperated_by<'a>(
input: &'a str,
on_skip: impl Fn(&'a str) -> bool,
) -> impl Iterator<Item = Vec<&'a str>> {
let mut current_block = Vec::new();
let mut lines = input.lines();
std::iter::from_fn(move || {
while let Some(next_line) = lines.next() {
if on_skip(next_line) {
if !current_block.is_empty() {
let to_return = std::mem::take(&mut current_block);
return Some(to_return);
}
} else {
current_block.push(next_line);
}
}
if !current_block.is_empty() {
let to_return = std::mem::take(&mut current_block);
return Some(to_return);
}
None
})
}
pub fn blocks_of_lines_seperated_by_empty_lines<'a>(
input: &'a str,
) -> impl Iterator<Item = Vec<&'a str>> {
blocks_of_lines_seperated_by(input, |line| line.trim().is_empty())
}
#[cfg(test)]
mod testing {
use std::vec;
use super::*;
#[test]
fn split_blocks_by_empty_lines() {
const INPUT: &str = "
1st
2st
3st
4st
5st
";
let expected = vec![vec!["1st", "2st"], vec!["3st"], vec!["4st"], vec!["5st"]];
let actual: Vec<Vec<&str>> =
blocks_of_lines_seperated_by(INPUT, |line| line.trim().is_empty()).collect();
assert_eq!(expected, actual);
}
}