#![deny(clippy::all)]
#![warn(clippy::pedantic)]
#![deny(missing_docs)]
pub mod aggregation;
pub mod existence;
pub mod signals;
pub use aggregation::evidence::{confidence_to_prob, family_multiplier, logit, vector_to_family};
pub use aggregation::{
compute_modifiers, passes_not_present_gate, EvidenceAccumulator, EvidenceModifiers,
ModifierResult, PreconditionBlock, PreconditionDecision, StopDecision, StopRule,
};
pub use existence::{burst_result, header_diff_result, SignalFamily};
pub use signals::header::{is_rate_limit_header, rate_limit_diff};
use parlov_core::{DifferentialSet, OracleClass, OracleResult, StrategyOutcome};
#[derive(Debug, thiserror::Error)]
pub enum AnalyzerError {
#[error("insufficient samples — collect at least {required} before calling analyze")]
InsufficientSamples {
required: usize,
},
}
pub enum SampleDecision {
Complete(Box<OracleResult>, StrategyOutcome),
NeedMore,
}
pub trait Analyzer: Send + Sync {
fn evaluate(&self, data: &DifferentialSet) -> SampleDecision;
fn oracle_class(&self) -> OracleClass;
fn analyze(&self, data: &DifferentialSet) -> Result<OracleResult, AnalyzerError> {
match self.evaluate(data) {
SampleDecision::Complete(result, _outcome) => Ok(*result),
SampleDecision::NeedMore => Err(AnalyzerError::InsufficientSamples {
required: self.required_samples(),
}),
}
}
fn required_samples(&self) -> usize {
1
}
}