use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum DeltaOp {
Upsert,
Delete,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Delta {
pub resource: String,
pub record_id: String,
pub op: DeltaOp,
pub payload: serde_json::Value,
pub occurred_at: DateTime<Utc>,
pub provenance: Provenance,
}
impl Delta {
pub fn upsert(
resource: impl Into<String>,
record_id: impl Into<String>,
payload: serde_json::Value,
source: impl Into<String>,
) -> Self {
Self {
resource: resource.into(),
record_id: record_id.into(),
op: DeltaOp::Upsert,
payload,
occurred_at: Utc::now(),
provenance: Provenance::new(source),
}
}
pub fn delete(
resource: impl Into<String>,
record_id: impl Into<String>,
source: impl Into<String>,
) -> Self {
Self {
resource: resource.into(),
record_id: record_id.into(),
op: DeltaOp::Delete,
payload: serde_json::Value::Null,
occurred_at: Utc::now(),
provenance: Provenance::new(source),
}
}
#[must_use]
pub fn with_confidence(mut self, confidence: f32) -> Self {
self.provenance.confidence = confidence.clamp(0.0, 1.0);
self
}
#[must_use]
pub fn at(mut self, ts: DateTime<Utc>) -> Self {
self.occurred_at = ts;
self
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Provenance {
pub source: String,
pub confidence: f32,
}
impl Provenance {
pub fn new(source: impl Into<String>) -> Self {
Self {
source: source.into(),
confidence: 1.0,
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MirroredRecord {
pub resource: String,
pub record_id: String,
pub payload: serde_json::Value,
pub source: String,
pub last_synced_at: DateTime<Utc>,
pub confidence: f32,
pub version: i64,
}