use std::sync::Arc;
use crate::Href;
use crate::base::Property;
use crate::sync::analysis::{ItemWithData, ResolvedMapping};
use crate::sync::status::StatusVersions;
use super::operation::{ItemOp, MappingUidSource, PropertyOp, WriteInA, WriteInB, WriteMode};
use super::status::{MappingUid, Side};
pub use super::plan::resolve_conflicts;
#[derive(PartialEq, Debug, Clone)]
pub struct ConflictInfo {
pub a: ItemWithData,
pub b: ItemWithData,
pub old: Option<StatusVersions>,
pub collection_a: Href,
pub collection_b: Href,
}
pub trait ConflictResolver: Send + Sync {
fn resolve_item(&self, conflict: ConflictInfo, mapping_uid: MappingUid) -> ItemOp;
fn resolve_property(
&self,
property: Property,
value_a: String,
value_b: String,
mapping: Arc<ResolvedMapping>,
mapping_uid: MappingUid,
) -> PropertyOp;
}
#[derive(Debug, Clone, Copy)]
pub struct KeepAResolver;
impl ConflictResolver for KeepAResolver {
fn resolve_item(&self, conflict: ConflictInfo, mapping_uid: MappingUid) -> ItemOp {
let ConflictInfo { a, b, old, .. } = conflict;
let mode = match old {
Some(old) => WriteMode::UpdateExisting { old },
None => WriteMode::UpdateNew {
target: b.state.version,
},
};
ItemOp::WriteInB(WriteInB {
source_a: a.into(),
mode,
mapping_uid: MappingUidSource::Immediate(mapping_uid),
on_complete: None,
})
}
fn resolve_property(
&self,
property: Property,
value_a: String,
_value_b: String,
mapping: Arc<ResolvedMapping>,
mapping_uid: MappingUid,
) -> PropertyOp {
PropertyOp::Write {
property,
value: value_a,
side: Side::B,
mapping,
mapping_uid: MappingUidSource::Immediate(mapping_uid),
deletion_completion: None,
}
}
}
#[derive(Debug, Clone, Copy)]
pub struct KeepBResolver;
impl ConflictResolver for KeepBResolver {
fn resolve_item(&self, conflict: ConflictInfo, mapping_uid: MappingUid) -> ItemOp {
let ConflictInfo { a, b, old, .. } = conflict;
let mode = match old {
Some(old) => WriteMode::UpdateExisting { old },
None => WriteMode::UpdateNew {
target: a.state.version,
},
};
ItemOp::WriteInA(WriteInA {
source_b: b.into(),
mode,
mapping_uid: MappingUidSource::Immediate(mapping_uid),
on_complete: None,
})
}
fn resolve_property(
&self,
property: Property,
_value_a: String,
value_b: String,
mapping: Arc<ResolvedMapping>,
mapping_uid: MappingUid,
) -> PropertyOp {
PropertyOp::Write {
property,
value: value_b,
side: Side::A,
mapping,
mapping_uid: MappingUidSource::Immediate(mapping_uid),
deletion_completion: None,
}
}
}