1use sui_compat::store_path::StorePath;
8use crate::traits::StoreResult;
9
10#[derive(Debug, Clone)]
12pub struct GenerationalPath {
13 pub path: StorePath,
15 pub generation: u64,
17 pub previous_hash: Option<String>,
19}
20
21#[derive(Debug, Clone, Default)]
23pub struct ImpactReport {
24 pub affected_paths: Vec<StorePath>,
26 pub affected_point_count: usize,
28 pub estimated_cost: f64,
30}
31
32#[allow(async_fn_in_trait)]
38pub trait ConvergenceStore {
39 async fn convergence_requisites(&self, path: &StorePath) -> StoreResult<Vec<StorePath>>;
41
42 async fn convergence_referrers(&self, path: &StorePath) -> StoreResult<Vec<StorePath>>;
44
45 async fn convergence_impact(&self, path: &StorePath) -> StoreResult<ImpactReport>;
47
48 async fn convergence_generation(&self, path: &StorePath) -> StoreResult<u64>;
50
51 async fn convergence_history(
53 &self,
54 path: &StorePath,
55 ) -> StoreResult<Vec<GenerationalPath>>;
56}
57
58pub struct DefaultConvergenceStore;
61
62impl ConvergenceStore for DefaultConvergenceStore {
63 async fn convergence_requisites(&self, _path: &StorePath) -> StoreResult<Vec<StorePath>> {
64 Ok(Vec::new())
66 }
67
68 async fn convergence_referrers(&self, _path: &StorePath) -> StoreResult<Vec<StorePath>> {
69 Ok(Vec::new())
70 }
71
72 async fn convergence_impact(&self, _path: &StorePath) -> StoreResult<ImpactReport> {
73 Ok(ImpactReport::default())
74 }
75
76 async fn convergence_generation(&self, _path: &StorePath) -> StoreResult<u64> {
77 Ok(0)
78 }
79
80 async fn convergence_history(
81 &self,
82 _path: &StorePath,
83 ) -> StoreResult<Vec<GenerationalPath>> {
84 Ok(Vec::new())
85 }
86}
87
88#[cfg(test)]
89mod tests {
90 use super::*;
91
92 #[tokio::test]
93 async fn test_default_convergence_store() {
94 let store = DefaultConvergenceStore;
95 let path = StorePath::from_basename("0000000000000000000000000000000a-test")
96 .unwrap();
97
98 let requisites = store.convergence_requisites(&path).await.unwrap();
99 assert!(requisites.is_empty());
100
101 let referrers = store.convergence_referrers(&path).await.unwrap();
102 assert!(referrers.is_empty());
103
104 let impact = store.convergence_impact(&path).await.unwrap();
105 assert_eq!(impact.affected_point_count, 0);
106
107 let generation = store.convergence_generation(&path).await.unwrap();
108 assert_eq!(generation, 0);
109
110 let history = store.convergence_history(&path).await.unwrap();
111 assert!(history.is_empty());
112 }
113
114 #[test]
115 fn test_generational_path() {
116 let path = StorePath::from_basename("0000000000000000000000000000000a-test")
117 .unwrap();
118 let gp = GenerationalPath {
119 path,
120 generation: 42,
121 previous_hash: Some("blake3:abc123".into()),
122 };
123 assert_eq!(gp.generation, 42);
124 assert!(gp.previous_hash.is_some());
125 }
126
127 #[test]
128 fn test_impact_report_default() {
129 let report = ImpactReport::default();
130 assert!(report.affected_paths.is_empty());
131 assert_eq!(report.affected_point_count, 0);
132 assert_eq!(report.estimated_cost, 0.0);
133 }
134}