use std::path::Path;
use osmic_core::error::{OsmicError, OsmicResult};
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ReplicationState {
pub sequence_number: u64,
pub timestamp: String,
pub base_url: String,
}
impl ReplicationState {
pub fn load(state_dir: &Path) -> OsmicResult<Self> {
let path = state_dir.join("state.json");
let data = std::fs::read_to_string(&path)
.map_err(|e| OsmicError::Other(format!("Failed to read state: {e}")))?;
serde_json::from_str(&data)
.map_err(|e| OsmicError::Other(format!("Failed to parse state: {e}")))
}
pub fn save(&self, state_dir: &Path) -> OsmicResult<()> {
std::fs::create_dir_all(state_dir)
.map_err(|e| OsmicError::Other(format!("Failed to create state dir: {e}")))?;
let path = state_dir.join("state.json");
let data = serde_json::to_string_pretty(self)
.map_err(|e| OsmicError::Other(format!("Failed to serialize state: {e}")))?;
std::fs::write(&path, data)
.map_err(|e| OsmicError::Other(format!("Failed to write state: {e}")))
}
pub fn next_osc_url(&self) -> String {
let seq = self.sequence_number + 1;
let a = seq / 1_000_000;
let b = (seq / 1_000) % 1_000;
let c = seq % 1_000;
format!(
"{}/{:03}/{:03}/{:03}.osc.gz",
self.base_url.trim_end_matches('/'),
a,
b,
c
)
}
pub fn init(base_url: &str, sequence_number: u64) -> Self {
Self {
sequence_number,
timestamp: String::new(),
base_url: base_url.to_string(),
}
}
}