use log::debug;
use crate::{monitor_types::EndCondition, telemetry::Coverage};
#[derive(Default, Clone, Debug)]
pub struct CoverageInfo {
pub coverage: Coverage,
}
impl CoverageInfo {
pub fn new(coverage: Coverage) -> Self {
Self { coverage }
}
pub fn is_covered(&self, goal: String) -> bool {
*self.coverage.get(&goal).unwrap_or(&0) > 0
}
pub fn covered(&self, goal: String) -> u64 {
*self.coverage.get(&goal).unwrap_or(&0)
}
pub fn merge(&mut self, rhs: &CoverageInfo) {
for (k, v) in rhs.coverage.iter() {
*self.coverage.get_mut(k).unwrap_or(&mut 0) += v;
}
}
}
impl From<Coverage> for CoverageInfo {
fn from(coverage: Coverage) -> Self {
Self { coverage }
}
}
pub type ExecutionId = u32;
pub trait ExecutionObserver {
fn before(&mut self, _eid: ExecutionId) {}
fn after(&mut self, _eid: ExecutionId, _end_condition: &EndCondition, _c: CoverageInfo) {}
fn at_end_of_exploration(&mut self) {}
}
#[doc(hidden)] pub fn cover_goal(c: String, module: &'static str, file: &'static str, line: u32) {
crate::ExecutionState::with(|s| {
debug!("Covered {c}");
let mut must = s.must.borrow_mut();
let eid = must.telemetry.coverage.current_eid();
must.telemetry.coverage.cover(eid, c, module, file, line);
});
}
pub fn is_covered(c: String) -> bool {
crate::ExecutionState::with(|s| {
let must = s.must.borrow();
must.telemetry.coverage.is_covered(c)
})
}
pub fn covered(c: String) -> u64 {
crate::ExecutionState::with(|s| {
let must = s.must.borrow();
must.telemetry.coverage.covered(c)
})
}
#[macro_export]
macro_rules! cover {
($name:expr) => {
let module = std::module_path!();
let file = std::file!();
let line = std::line!();
$crate::coverage::cover_goal($name.into(), module, file, line); };
($name:expr, $cond:expr $(,)?) => {
if $cond {
let module = std::module_path!();
let file = std::file!();
let line = std::line!();
$crate::coverage::cover_goal($name.into(), module, file, line); }
};
}