use anyhow::{anyhow, bail, Result};
use mimir_core::replicate::{ApplyStats, SyncBatch};
use serde::Deserialize;
#[derive(Debug, Deserialize)]
pub struct PushResult {
pub applied: ApplyStats,
pub watermark: i64,
}
fn auth(token: &str) -> String {
format!("Bearer {token}")
}
pub fn pull(endpoint: &str, token: &str, since: i64) -> Result<SyncBatch> {
let url = format!("{}/sync/pull?since={since}", endpoint.trim_end_matches('/'));
match ureq::get(&url).set("Authorization", &auth(token)).call() {
Ok(r) => Ok(r.into_json::<SyncBatch>()?),
Err(ureq::Error::Status(401, _)) => {
bail!("hub rejected the token (401) — check MIMIR_SYNC_TOKEN")
}
Err(ureq::Error::Status(code, _)) => bail!("hub pull failed: HTTP {code}"),
Err(e) => Err(anyhow!("hub unreachable at {endpoint}: {e}")),
}
}
pub fn push(endpoint: &str, token: &str, batch: &SyncBatch) -> Result<PushResult> {
let url = format!("{}/sync/push", endpoint.trim_end_matches('/'));
match ureq::post(&url)
.set("Authorization", &auth(token))
.send_json(batch)
{
Ok(r) => Ok(r.into_json::<PushResult>()?),
Err(ureq::Error::Status(401, _)) => {
bail!("hub rejected the token (401) — check MIMIR_SYNC_TOKEN")
}
Err(ureq::Error::Status(code, _)) => bail!("hub push failed: HTTP {code}"),
Err(e) => Err(anyhow!("hub unreachable at {endpoint}: {e}")),
}
}