use crate::{
base::{FetchedItem, Item, ItemHash, ItemVersion},
sync::status::{ItemPairStatus, ItemState, MappingUid, StatusVersions},
};
#[derive(PartialEq, Clone)]
pub struct ItemWithData {
pub state: ItemState,
pub data: Item,
}
#[derive(Clone, PartialEq, Debug)]
pub struct ItemSource {
pub state: ItemState,
pub data: Option<Item>,
}
impl From<ItemWithData> for ItemSource {
fn from(item: ItemWithData) -> Self {
ItemSource {
state: item.state,
data: Some(item.data),
}
}
}
impl ItemSource {
#[must_use]
pub fn to_item_ver(&self) -> ItemVersion {
self.state.version.clone()
}
}
impl std::fmt::Debug for ItemWithData {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("ItemWithData")
.field("state", &self.state)
.field("data", &"<omitted>")
.finish()
}
}
pub enum ItemAnalysis {
New(NewItem),
Existing(ExistingItem),
}
pub enum NewItem {
OnlyA { a: ItemWithData },
OnlyB { b: ItemWithData },
OnBoth { a: ItemWithData, b: ItemWithData },
}
pub struct ExistingItem {
pub status: ItemPairStatus,
pub current: ExistingItemPresence,
}
impl ExistingItem {
#[must_use]
pub fn new(
current_a: Option<SideState>,
current_b: Option<SideState>,
status: ItemPairStatus,
) -> ExistingItem {
let current = match (current_a, current_b) {
(None, None) => ExistingItemPresence::OnNeither,
(Some(a), None) => ExistingItemPresence::OnlyA { a },
(None, Some(b)) => ExistingItemPresence::OnlyB { b },
(Some(a), Some(b)) => ExistingItemPresence::OnBoth { a, b },
};
ExistingItem { status, current }
}
#[must_use]
pub fn mapping_uid(&self) -> MappingUid {
self.status.mapping_uid
}
}
pub enum ExistingItemPresence {
OnNeither,
OnlyA { a: SideState },
OnlyB { b: SideState },
OnBoth { a: SideState, b: SideState },
}
#[derive(Clone, Debug)]
pub enum SideState {
Changed { state: ItemState, data: Item },
Unchanged { state: ItemState },
}
impl SideState {
#[must_use]
pub fn from_fetched(FetchedItem { href, item, etag }: FetchedItem) -> Self {
Self::Changed {
state: ItemState {
version: ItemVersion::new(href, etag),
uid: item.ident(),
hash: item.hash(),
},
data: item,
}
}
#[must_use]
pub fn unchanged(state: ItemState) -> Self {
Self::Unchanged { state }
}
#[must_use]
pub fn state(&self) -> &ItemState {
match self {
Self::Changed { state, .. } | Self::Unchanged { state } => state,
}
}
#[must_use]
pub fn into_item_ver(self) -> ItemVersion {
match self {
SideState::Changed { state, .. } | SideState::Unchanged { state } => state.version,
}
}
}
#[derive(PartialEq, Debug, Clone)]
pub enum StatusAction {
Insert {
uid: String,
hash: ItemHash,
versions: StatusVersions,
},
Update {
hash: ItemHash,
old: StatusVersions,
new: StatusVersions,
},
Clear { uid: String },
}
impl std::fmt::Display for StatusAction {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
StatusAction::Insert { uid, .. } => write!(f, "save to status (uid: {uid})"),
StatusAction::Update { old, .. } => {
write!(f, "update in status (a.href: {})", old.a.href)
}
StatusAction::Clear { uid } => write!(f, "clear from status (uid: {uid})"),
}
}
}