use sui_compat::store_path::StorePath;
use crate::traits::StoreResult;
#[derive(Debug, Clone)]
pub struct GenerationalPath {
pub path: StorePath,
pub generation: u64,
pub previous_hash: Option<String>,
}
#[derive(Debug, Clone, Default)]
pub struct ImpactReport {
pub affected_paths: Vec<StorePath>,
pub affected_point_count: usize,
pub estimated_cost: f64,
}
#[allow(async_fn_in_trait)]
pub trait ConvergenceStore {
async fn convergence_requisites(&self, path: &StorePath) -> StoreResult<Vec<StorePath>>;
async fn convergence_referrers(&self, path: &StorePath) -> StoreResult<Vec<StorePath>>;
async fn convergence_impact(&self, path: &StorePath) -> StoreResult<ImpactReport>;
async fn convergence_generation(&self, path: &StorePath) -> StoreResult<u64>;
async fn convergence_history(
&self,
path: &StorePath,
) -> StoreResult<Vec<GenerationalPath>>;
}
pub struct DefaultConvergenceStore;
impl ConvergenceStore for DefaultConvergenceStore {
async fn convergence_requisites(&self, _path: &StorePath) -> StoreResult<Vec<StorePath>> {
Ok(Vec::new())
}
async fn convergence_referrers(&self, _path: &StorePath) -> StoreResult<Vec<StorePath>> {
Ok(Vec::new())
}
async fn convergence_impact(&self, _path: &StorePath) -> StoreResult<ImpactReport> {
Ok(ImpactReport::default())
}
async fn convergence_generation(&self, _path: &StorePath) -> StoreResult<u64> {
Ok(0)
}
async fn convergence_history(
&self,
_path: &StorePath,
) -> StoreResult<Vec<GenerationalPath>> {
Ok(Vec::new())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[tokio::test]
async fn test_default_convergence_store() {
let store = DefaultConvergenceStore;
let path = StorePath::from_basename("0000000000000000000000000000000a-test")
.unwrap();
let requisites = store.convergence_requisites(&path).await.unwrap();
assert!(requisites.is_empty());
let referrers = store.convergence_referrers(&path).await.unwrap();
assert!(referrers.is_empty());
let impact = store.convergence_impact(&path).await.unwrap();
assert_eq!(impact.affected_point_count, 0);
let generation = store.convergence_generation(&path).await.unwrap();
assert_eq!(generation, 0);
let history = store.convergence_history(&path).await.unwrap();
assert!(history.is_empty());
}
#[test]
fn test_generational_path() {
let path = StorePath::from_basename("0000000000000000000000000000000a-test")
.unwrap();
let gp = GenerationalPath {
path,
generation: 42,
previous_hash: Some("blake3:abc123".into()),
};
assert_eq!(gp.generation, 42);
assert!(gp.previous_hash.is_some());
}
#[test]
fn test_impact_report_default() {
let report = ImpactReport::default();
assert!(report.affected_paths.is_empty());
assert_eq!(report.affected_point_count, 0);
assert_eq!(report.estimated_cost, 0.0);
}
}