use crate::error::MnemesError;
use crate::replica::ReplicaApplier;
use crate::replication::TrustedKeyRegistry;
#[derive(Debug, serde::Deserialize)]
pub struct SyncRequest {
pub home_device_id: String,
pub store_id: String,
pub start_sequence: i64,
pub entries: Vec<SyncEntry>,
}
#[derive(Debug, serde::Deserialize)]
pub struct SyncEntry {
pub sequence: i64,
pub operation_kind: String,
pub payload_hex: String, }
#[derive(Debug, serde::Serialize)]
pub struct SyncResponse {
pub synced: usize,
pub next_sequence: i64,
pub has_more: bool,
pub errors: Vec<String>,
}
pub fn process_sync_request(
request: SyncRequest,
registry: &TrustedKeyRegistry,
replica_base_dir: &std::path::Path,
dispatch_fn: &dyn Fn(&rusqlite::Connection, &str, &[u8]) -> Result<(), MnemesError>,
) -> Result<SyncResponse, MnemesError> {
let replica_path = replica_base_dir.join(format!("{}.db", request.store_id));
let applier = ReplicaApplier::new(&replica_path, &request.home_device_id, &request.store_id);
let mut synced = 0;
let mut errors = Vec::new();
for entry in &request.entries {
let payload = match hex::decode(&entry.payload_hex) {
Ok(p) => p,
Err(e) => {
errors.push(format!("seq {} hex: {e}", entry.sequence));
continue;
}
};
let _ = registry;
match applier.apply_entry(entry.sequence, &entry.operation_kind, &payload, &|conn| {
dispatch_fn(conn, &entry.operation_kind, &payload)
}) {
Ok(_) => synced += 1,
Err(e) => {
errors.push(format!("seq {} apply: {e}", entry.sequence));
}
}
}
Ok(SyncResponse {
synced,
next_sequence: request.start_sequence + synced as i64 + errors.len() as i64,
has_more: false,
errors,
})
}