use std::path::Path;
use super::diagnosis::TargetContract;
use super::execute::{execute, journal_workspace, ExecuteOutcome};
use super::query_error;
use super::state::{MigrationState, Phase};
use super::switchover::{switch_over, SwitchOutcome};
use super::validate::{validate_destination, ValidationOutcome};
use crate::embedder::Embedder;
#[derive(Debug)]
pub struct MigrateOutcome {
pub executed: Option<ExecuteOutcome>,
pub validated: Option<ValidationOutcome>,
pub switched: SwitchOutcome,
}
pub fn migrate(
store: &Path,
scratch_parent: &Path,
target: &TargetContract,
destination: &Path,
embedder: &dyn Embedder,
batch: usize,
) -> Result<MigrateOutcome, crate::MemoryError> {
let (executed, validated) = if past_validation(destination)? {
(None, None)
} else {
let executed = execute(store, scratch_parent, target, destination, embedder, batch)?;
let validated = validate_destination(store, destination, target, batch)?;
(Some(executed), Some(validated))
};
let switched = switch_over(store, destination)?;
Ok(MigrateOutcome {
executed,
validated,
switched,
})
}
fn past_validation(destination: &Path) -> Result<bool, crate::MemoryError> {
let workspace = journal_workspace(destination)?;
let state = MigrationState::read(&workspace).map_err(query_error)?;
Ok(state.is_some_and(|state| state.phase >= Phase::DestinationValidated))
}