pub struct ContentLines<'a> {
inner: std::str::Lines<'a>,
}
impl<'a> ContentLines<'a> {
#[must_use]
pub fn new(content: &'a str) -> Self {
Self {
inner: content.lines(),
}
}
}
impl<'a> Iterator for ContentLines<'a> {
type Item = &'a str;
fn next(&mut self) -> Option<Self::Item> {
loop {
let line = self.inner.next()?;
let trimmed = line.trim();
if trimmed.is_empty() || trimmed.starts_with('#') {
continue;
}
return Some(trimmed);
}
}
}
#[inline]
#[must_use]
pub fn is_section_header(line: &str) -> bool {
line.starts_with('!')
}
#[inline]
#[must_use]
pub fn strip_inline_comment(line: &str) -> &str {
if let Some(pos) = line.find('#') {
line[..pos].trim_end()
} else {
line
}
}