#[derive(Debug, PartialEq, Eq)]
pub enum BraceSegment<'a> {
Literal(&'a str),
Expr(&'a str),
}
pub fn scan_brace_segments(text: &str) -> Result<Vec<BraceSegment<'_>>, usize> {
let mut segments = Vec::new();
let mut remaining = text;
let mut consumed = 0;
while let Some(open) = remaining.find('{') {
if open > 0 {
segments.push(BraceSegment::Literal(&remaining[..open]));
}
let after = &remaining[open + 1..];
let close = after.find('}').ok_or(consumed + open)?;
segments.push(BraceSegment::Expr(&after[..close]));
consumed += open + 1 + close + 1;
remaining = &after[close + 1..];
}
if !remaining.is_empty() {
segments.push(BraceSegment::Literal(remaining));
}
Ok(segments)
}
#[cfg(test)]
#[path = "interpolation_tests.rs"]
mod tests;