pub mod draw;
pub mod records;
pub mod repredict;
pub mod sample;
pub mod score;
pub mod score_buckets;
pub mod stats;
pub mod subsample;
mod merges;
mod population;
pub(crate) mod redact;
mod report_md;
mod verdict;
use std::path::{Path, PathBuf};
use rusqlite::Connection;
use thiserror::Error;
pub use records::{SampleRecord, StrataSummary, Stratum};
pub use repredict::{run_repredict, RepredictParams, RepredictSummary};
pub use sample::{run_sample, SampleParams, SampleSummary};
pub use score::{run_score, run_score_with_buckets, ScoreParams, ScoreReport};
pub use score_buckets::{BucketRow, BucketScores};
pub use subsample::{run_subsample, SubsampleParams, SubsampleSummary};
#[derive(Debug, Error)]
#[non_exhaustive]
pub enum EvalError {
#[error("database error: {0}")]
Db(#[from] rusqlite::Error),
#[error(transparent)]
Core(#[from] crate::core::errors::TgaError),
#[error("rule engine: {0}")]
Classify(#[from] crate::classify::ClassifyError),
#[error("refusing to run: {0} is not opened read-only")]
NotReadOnly(PathBuf),
#[error("{path}: {source}")]
Io {
path: PathBuf,
source: std::io::Error,
},
#[error("{path}: {source}")]
Json {
path: PathBuf,
source: serde_json::Error,
},
#[error("{path}: {source}")]
Csv {
path: PathBuf,
source: csv::Error,
},
#[error("{0}")]
Invalid(String),
}
pub type Result<T> = std::result::Result<T, EvalError>;
pub(crate) fn io_err(path: &Path) -> impl FnOnce(std::io::Error) -> EvalError + '_ {
move |source| EvalError::Io {
path: path.to_path_buf(),
source,
}
}
pub fn config_categories(config: &crate::core::config::Config) -> Result<Vec<String>> {
Ok(crate::classify::ClassificationPipeline::new(config.clone()).known_categories()?)
}
pub fn open_eval_db(path: &Path) -> Result<Connection> {
let conn = crate::core::inspect::open_read_only(path)?;
if !conn.is_readonly(rusqlite::MAIN_DB)? {
return Err(EvalError::NotReadOnly(path.to_path_buf()));
}
conn.pragma_update(None, "query_only", true)?;
Ok(conn)
}