use std::str::FromStr;
use crate::errors::ParseError;
use crate::tl::{Category, Definition};
pub(crate) struct TlIterator<'a> {
lines: std::str::Lines<'a>,
category: Category,
pending: String,
}
impl<'a> TlIterator<'a> {
pub(crate) fn new(src: &'a str) -> Self {
Self {
lines: src.lines(),
category: Category::Types,
pending: String::new(),
}
}
fn handle_separator(&mut self, line: &str) -> bool {
let trimmed = line.trim();
match trimmed {
"---functions---" => {
self.category = Category::Functions;
true
}
"---types---" => {
self.category = Category::Types;
true
}
_ => false,
}
}
}
impl<'a> Iterator for TlIterator<'a> {
type Item = Result<Definition, ParseError>;
fn next(&mut self) -> Option<Self::Item> {
loop {
let line = self.lines.next()?;
let trimmed = line.trim();
if trimmed.is_empty() || trimmed.starts_with("//") {
continue;
}
if self.handle_separator(trimmed) {
continue;
}
self.pending.push(' ');
self.pending.push_str(trimmed);
if !trimmed.ends_with(';') {
continue;
}
let raw = std::mem::take(&mut self.pending);
let raw = raw.trim();
let raw = raw.trim_end_matches(';').trim();
if raw.is_empty() {
continue;
}
let result = Definition::from_str(raw).map(|mut d| {
d.category = self.category;
d
});
return Some(result);
}
}
}