forked from Deuxfleurs/garage
73 lines
1.5 KiB
Rust
73 lines
1.5 KiB
Rust
|
use serde::{Deserialize, Serialize};
|
||
|
|
||
|
use crate::crdt::crdt::*;
|
||
|
|
||
|
/// Deletable object (once deleted, cannot go back)
|
||
|
#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq)]
|
||
|
pub enum Deletable<T> {
|
||
|
Present(T),
|
||
|
Deleted,
|
||
|
}
|
||
|
|
||
|
impl<T: Crdt> Deletable<T> {
|
||
|
/// Create a new deletable object that isn't deleted
|
||
|
pub fn present(v: T) -> Self {
|
||
|
Self::Present(v)
|
||
|
}
|
||
|
/// Create a new deletable object that is deleted
|
||
|
pub fn delete() -> Self {
|
||
|
Self::Deleted
|
||
|
}
|
||
|
/// As option
|
||
|
pub fn as_option(&self) -> Option<&T> {
|
||
|
match self {
|
||
|
Self::Present(v) => Some(v),
|
||
|
Self::Deleted => None,
|
||
|
}
|
||
|
}
|
||
|
/// As option, mutable
|
||
|
pub fn as_option_mut(&mut self) -> Option<&mut T> {
|
||
|
match self {
|
||
|
Self::Present(v) => Some(v),
|
||
|
Self::Deleted => None,
|
||
|
}
|
||
|
}
|
||
|
/// Into option
|
||
|
pub fn into_option(self) -> Option<T> {
|
||
|
match self {
|
||
|
Self::Present(v) => Some(v),
|
||
|
Self::Deleted => None,
|
||
|
}
|
||
|
}
|
||
|
/// Is object deleted?
|
||
|
pub fn is_deleted(&self) -> bool {
|
||
|
matches!(self, Self::Deleted)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
impl<T> From<Option<T>> for Deletable<T> {
|
||
|
fn from(v: Option<T>) -> Self {
|
||
|
v.map(Self::Present).unwrap_or(Self::Deleted)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
impl<T> From<Deletable<T>> for Option<T> {
|
||
|
fn from(v: Deletable<T>) -> Option<T> {
|
||
|
match v {
|
||
|
Deletable::Present(v) => Some(v),
|
||
|
Deletable::Deleted => None,
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
impl<T: Crdt> Crdt for Deletable<T> {
|
||
|
fn merge(&mut self, other: &Self) {
|
||
|
if let Deletable::Present(v) = self {
|
||
|
match other {
|
||
|
Deletable::Deleted => *self = Deletable::Deleted,
|
||
|
Deletable::Present(v2) => v.merge(v2),
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|