use crate::{EvaluationConfig, LibmagicError};
use serde::{Deserialize, Serialize};
mod engine;
pub mod offset;
pub mod operators;
pub mod strength;
pub mod types;
pub use engine::{evaluate_rules, evaluate_rules_with_config, evaluate_single_rule};
#[derive(Debug, Clone)]
pub struct EvaluationContext {
current_offset: usize,
recursion_depth: u32,
config: EvaluationConfig,
}
impl EvaluationContext {
#[must_use]
pub const fn new(config: EvaluationConfig) -> Self {
Self {
current_offset: 0,
recursion_depth: 0,
config,
}
}
#[must_use]
pub const fn current_offset(&self) -> usize {
self.current_offset
}
pub fn set_current_offset(&mut self, offset: usize) {
self.current_offset = offset;
}
#[must_use]
pub const fn recursion_depth(&self) -> u32 {
self.recursion_depth
}
pub fn increment_recursion_depth(&mut self) -> Result<(), LibmagicError> {
if self.recursion_depth >= self.config.max_recursion_depth {
return Err(LibmagicError::EvaluationError(
crate::error::EvaluationError::recursion_limit_exceeded(self.recursion_depth),
));
}
self.recursion_depth += 1;
Ok(())
}
pub fn decrement_recursion_depth(&mut self) -> Result<(), LibmagicError> {
if self.recursion_depth == 0 {
return Err(LibmagicError::EvaluationError(
crate::error::EvaluationError::internal_error(
"Attempted to decrement recursion depth below 0",
),
));
}
self.recursion_depth -= 1;
Ok(())
}
#[must_use]
pub const fn config(&self) -> &EvaluationConfig {
&self.config
}
#[must_use]
pub const fn should_stop_at_first_match(&self) -> bool {
self.config.stop_at_first_match
}
#[must_use]
pub const fn max_string_length(&self) -> usize {
self.config.max_string_length
}
#[must_use]
pub const fn enable_mime_types(&self) -> bool {
self.config.enable_mime_types
}
#[must_use]
pub const fn timeout_ms(&self) -> Option<u64> {
self.config.timeout_ms
}
pub fn reset(&mut self) {
self.current_offset = 0;
self.recursion_depth = 0;
}
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct RuleMatch {
pub message: String,
pub offset: usize,
pub level: u32,
pub value: crate::parser::ast::Value,
pub type_kind: crate::parser::ast::TypeKind,
pub confidence: f64,
}
impl RuleMatch {
#[must_use]
pub fn calculate_confidence(level: u32) -> f64 {
(0.3 + (f64::from(level) * 0.2)).min(1.0)
}
}
#[cfg(test)]
mod tests;