use crate::SyncTarget;
use async_trait::async_trait;
use origin_domain::{Result, SyncId, SyncState, ThrottleReason};
use std::fmt::Debug;
use time::Duration;
use tokio_util::sync::CancellationToken;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct SyncThrottle {
pub delay: Duration,
pub reason: ThrottleReason,
}
impl SyncThrottle {
pub fn quota(delay: Duration) -> Self {
Self {
delay,
reason: ThrottleReason::Quota,
}
}
pub fn server_interval(delay: Duration) -> Self {
Self {
delay,
reason: ThrottleReason::ServerInterval,
}
}
}
#[derive(Debug, Clone, Default, PartialEq, Eq)]
pub struct SyncReport {
pub changed: u64,
pub etag: Option<String>,
pub last_modified: Option<String>,
pub throttle: Option<SyncThrottle>,
}
impl SyncReport {
pub fn changed(changed: u64) -> Self {
Self {
changed,
..Self::default()
}
}
pub fn with_etag(mut self, etag: impl Into<String>) -> Self {
self.etag = Some(etag.into());
self
}
pub fn with_last_modified(mut self, last_modified: impl Into<String>) -> Self {
self.last_modified = Some(last_modified.into());
self
}
pub fn with_throttle(mut self, throttle: SyncThrottle) -> Self {
self.throttle = Some(throttle);
self
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum SyncResult {
Updated(SyncReport),
NotModified,
}
#[derive(Debug)]
pub struct SyncContext {
pub sync_id: SyncId,
pub target: SyncTarget,
pub state: SyncState,
cancel: CancellationToken,
}
impl SyncContext {
pub(crate) fn new(
sync_id: SyncId,
target: SyncTarget,
state: SyncState,
cancel: CancellationToken,
) -> Self {
Self {
sync_id,
target,
state,
cancel,
}
}
pub fn etag(&self) -> Option<&str> {
self.state.etag.as_deref()
}
pub fn last_modified(&self) -> Option<&str> {
self.state.last_modified.as_deref()
}
pub fn is_cancelled(&self) -> bool {
self.cancel.is_cancelled()
}
pub async fn cancelled(&self) {
self.cancel.cancelled().await;
}
}
#[async_trait]
pub trait SyncSource: Debug + Send + Sync + 'static {
async fn sync(&self, context: &SyncContext) -> Result<SyncResult>;
}