use std::path::Path;
use async_trait::async_trait;
use super::topology_store::TopologyFileView;
use crate::application::error::SyncError;
use crate::domain::file_type::FileType;
use crate::domain::fingerprint::FileFingerprint;
use crate::domain::location::{LocationId, SyncSummary};
use crate::domain::view::{ErrorEntry, PendingEntry};
use crate::infra::backend::ProgressFn;
#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize)]
pub struct SyncReport {
pub scanned: usize,
pub scan_errors: Vec<SyncReportError>,
pub transfers_created: usize,
pub transferred: usize,
pub failed: usize,
pub errors: Vec<SyncReportError>,
#[serde(skip_serializing_if = "Vec::is_empty")]
pub conflicts: Vec<SyncReportConflict>,
}
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct SyncReportConflict {
pub file_id: String,
pub path: String,
pub locations: Vec<String>,
}
impl From<&crate::domain::distribute::ConflictEntry> for SyncReportConflict {
fn from(c: &crate::domain::distribute::ConflictEntry) -> Self {
Self {
file_id: c.topology_file_id().to_string(),
path: c.relative_path().to_string(),
locations: c
.variants()
.iter()
.map(|v| v.location_id().to_string())
.collect(),
}
}
}
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct SyncReportError {
pub path: String,
pub error: String,
}
#[derive(Debug, serde::Serialize)]
pub struct PutReport {
pub file_id: String,
pub is_new: bool,
pub transfers_created: usize,
}
#[async_trait]
pub trait SyncStoreSdk: Send + Sync {
async fn sync(&self) -> Result<SyncReport, SyncError>;
async fn sync_route(
&self,
src: &LocationId,
dest: &LocationId,
) -> Result<SyncReport, SyncError>;
async fn put(
&self,
path: &str,
file_type: FileType,
fingerprint: FileFingerprint,
origin: &LocationId,
embedded_id: Option<String>,
) -> Result<PutReport, SyncError>;
async fn delete(&self, path: &str) -> Result<usize, SyncError>;
async fn restore(&self, path: &str, revision: &str) -> Result<(), SyncError>;
async fn get(&self, path: &str) -> Result<Option<TopologyFileView>, SyncError>;
async fn list(
&self,
file_type: Option<FileType>,
limit: Option<usize>,
) -> Result<Vec<TopologyFileView>, SyncError>;
async fn status(&self) -> Result<SyncSummary, SyncError>;
async fn errors(&self) -> Result<Vec<ErrorEntry>, SyncError>;
async fn pending(&self, dest: &LocationId) -> Result<Vec<PendingEntry>, SyncError>;
fn locations(&self) -> Vec<LocationId>;
fn all_edges(&self) -> Vec<(LocationId, LocationId)>;
fn local_root(&self) -> Option<&Path>;
fn set_progress_callback(&self, _callback: Option<ProgressFn>) {}
}