1use crate::SyncTarget;
2use async_trait::async_trait;
3use origin_domain::{Result, SyncId, SyncState};
4use std::fmt::Debug;
5use tokio_util::sync::CancellationToken;
6
7#[derive(Debug, Clone, Default, PartialEq, Eq)]
9pub struct SyncReport {
10 pub changed: u64,
12 pub etag: Option<String>,
14 pub last_modified: Option<String>,
15}
16
17impl SyncReport {
18 pub fn changed(changed: u64) -> Self {
19 Self {
20 changed,
21 ..Self::default()
22 }
23 }
24
25 pub fn with_etag(mut self, etag: impl Into<String>) -> Self {
26 self.etag = Some(etag.into());
27 self
28 }
29
30 pub fn with_last_modified(mut self, last_modified: impl Into<String>) -> Self {
31 self.last_modified = Some(last_modified.into());
32 self
33 }
34}
35
36#[derive(Debug, Clone, PartialEq, Eq)]
38pub enum SyncResult {
39 Updated(SyncReport),
40 NotModified,
42}
43
44#[derive(Debug)]
46pub struct SyncContext {
47 pub sync_id: SyncId,
48 pub target: SyncTarget,
49 pub state: SyncState,
51 cancel: CancellationToken,
52}
53
54impl SyncContext {
55 pub(crate) fn new(
56 sync_id: SyncId,
57 target: SyncTarget,
58 state: SyncState,
59 cancel: CancellationToken,
60 ) -> Self {
61 Self {
62 sync_id,
63 target,
64 state,
65 cancel,
66 }
67 }
68
69 pub fn etag(&self) -> Option<&str> {
71 self.state.etag.as_deref()
72 }
73
74 pub fn last_modified(&self) -> Option<&str> {
76 self.state.last_modified.as_deref()
77 }
78
79 pub fn is_cancelled(&self) -> bool {
81 self.cancel.is_cancelled()
82 }
83
84 pub async fn cancelled(&self) {
85 self.cancel.cancelled().await;
86 }
87}
88
89#[async_trait]
94pub trait SyncSource: Debug + Send + Sync + 'static {
95 async fn sync(&self, context: &SyncContext) -> Result<SyncResult>;
96}