Skip to main content

safe_migrate/
api.rs

1use std::fmt;
2
3pub use crate::_internal::analysis::evidence::{
4    EvidenceCode, EvidenceLocation, EvidenceRecord, EvidenceScope,
5};
6pub use crate::_internal::analysis::outcome::AnalysisOutcome;
7pub use crate::_internal::analysis::state::AnalysisState;
8pub use crate::_internal::db::cache::DbCache;
9pub use crate::_internal::engine::config::Config;
10pub use crate::_internal::engine::engine::SafeMigrateEngine;
11pub use crate::_internal::report::reporter::Reporter;
12pub use crate::_internal::report::violations::ReportFinding;
13pub use crate::_internal::rules::RuleCapability;
14
15/// Stable error boundary for high-level library analysis helpers.
16#[derive(Debug)]
17pub enum AnalysisError {
18    InvalidCache(String),
19    Parse(Vec<String>),
20}
21
22impl fmt::Display for AnalysisError {
23    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
24        match self {
25            Self::InvalidCache(error) => write!(formatter, "invalid cache: {error}"),
26            Self::Parse(errors) => write!(formatter, "analysis failed: {}", errors.join("; ")),
27        }
28    }
29}
30
31impl std::error::Error for AnalysisError {}
32
33/// Analyze one migration using a validated cache and return immutable
34/// findings, confidence, and evidence. The helper owns the mutable state
35/// so callers cannot accidentally bypass cache validation or reuse state
36/// across unrelated analyses.
37pub fn analyze(
38    config: Config,
39    filename: impl Into<String>,
40    sql: impl Into<String>,
41    cache: DbCache,
42) -> Result<AnalysisOutcome<ReportFinding>, AnalysisError> {
43    analyze_chain(config, &[(filename.into(), sql.into())], cache)
44}
45
46/// Analyze an ordered migration chain with a fresh validated baseline.
47pub fn analyze_chain(
48    config: Config,
49    files: &[(String, String)],
50    cache: DbCache,
51) -> Result<AnalysisOutcome<ReportFinding>, AnalysisError> {
52    let mut state = AnalysisState::try_new(cache).map_err(AnalysisError::InvalidCache)?;
53    let engine = SafeMigrateEngine::new(config);
54    engine
55        .analyze_chain_outcome_with_locations(files, &mut state)
56        .map_err(AnalysisError::Parse)
57}