use crate::codemap::FileSpanRef;
use crate::eval::Evaluator;
#[derive(Default)]
pub(crate) struct BeforeStmt<'a, 'e: 'a> {
pub(crate) before_stmt: Vec<BeforeStmtFunc<'a, 'e>>,
pub(crate) instrument: bool,
}
#[doc(hidden)]
pub enum BeforeStmtFunc<'a, 'e: 'a> {
Fn(&'a dyn for<'v1> Fn(FileSpanRef, &mut Evaluator<'v1, 'a, 'e>)),
Dyn(Box<dyn BeforeStmtFuncDyn<'a, 'e>>),
}
impl<'a, 'e: 'a> BeforeStmtFunc<'a, 'e> {
pub(crate) fn call<'v>(
&mut self,
span: FileSpanRef,
eval: &mut Evaluator<'v, 'a, 'e>,
) -> crate::Result<()> {
match self {
BeforeStmtFunc::Fn(f) => {
f(span, eval);
Ok(())
}
BeforeStmtFunc::Dyn(d) => d.call(span, eval),
}
}
}
#[doc(hidden)]
pub trait BeforeStmtFuncDyn<'a, 'e: 'a> {
#[doc(hidden)]
fn call<'v>(
&mut self,
span: FileSpanRef,
eval: &mut Evaluator<'v, 'a, 'e>,
) -> crate::Result<()>;
}
impl<'a, 'e: 'a> BeforeStmt<'a, 'e> {
pub(crate) fn enabled(&self) -> bool {
self.instrument || !self.before_stmt.is_empty()
}
}
impl<'a, 'e: 'a> From<&'a dyn for<'v1> Fn(FileSpanRef, &mut Evaluator<'v1, 'a, 'e>)>
for BeforeStmtFunc<'a, 'e>
{
fn from(value: &'a dyn for<'v1> Fn(FileSpanRef, &mut Evaluator<'v1, 'a, 'e>)) -> Self {
Self::Fn(value)
}
}
impl<'a, 'e: 'a> From<Box<dyn BeforeStmtFuncDyn<'a, 'e>>> for BeforeStmtFunc<'a, 'e> {
fn from(value: Box<dyn BeforeStmtFuncDyn<'a, 'e>>) -> Self {
Self::Dyn(value)
}
}