use itertools::Itertools;
use crate::spans::{Point, Span};
use crate::ast;
impl ast::Ast {
pub fn find_point(&self, point: &Point) -> Option<&ast::Command> {
self.commands
.iter()
.find(|cmd| cmd.span().start <= *point && cmd.span().end >= *point)
}
pub fn find_run_commands(&self) -> impl Iterator<Item = &ast::Command> {
self.commands.iter().filter(|cmd| {
if let ast::Command::Generic(c) = &cmd {
c.name.contents == "run"
} else {
false
}
})
}
pub fn find_run_blocks(&self) -> impl Iterator<Item = Span> + '_ {
let run_definitions = self.find_run_commands();
let run_spans = run_definitions.map(|cmd| cmd.span());
std::iter::once(Span {
start: (0, 0).into(),
end: (0, 0).into(),
})
.chain(run_spans)
.tuple_windows()
.map(|(cmd1, cmd2)| Span {
start: cmd1.end,
end: cmd2.start,
})
}
}
#[cfg(test)]
mod test {
use crate::input_script::InputScript;
use pretty_assertions::assert_eq;
use super::*;
#[test]
#[allow(clippy::unwrap_used)]
fn test_find_run_commands() {
let file = include_str!("../../example_input_scripts/in.nemd");
let input_script = InputScript::new(file).unwrap();
let run_commands: Vec<_> = input_script.ast.find_run_commands().cloned().collect();
assert_eq!(run_commands.len(), 2);
assert_eq!(run_commands[0].span(), Span::from((132, 0)..(132, 17)));
assert_eq!(run_commands[1].span(), Span::from((146, 0)..(146, 6)));
}
}