use crate::anchor::InnerAnchor as Anchor;
use crate::*;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Deletion {
start: Anchor,
end: Anchor,
version_map: VersionMap,
deletion_ts: DeletionTs,
}
impl Deletion {
#[inline(always)]
pub fn deleted_by(&self) -> ReplicaId {
self.version_map.this_id()
}
#[inline(always)]
pub(crate) fn deletion_ts(&self) -> DeletionTs {
self.deletion_ts
}
#[inline(always)]
pub(crate) fn end(&self) -> Anchor {
self.end
}
#[inline]
pub(crate) fn is_no_op(&self) -> bool {
self.end.is_zero()
}
#[inline]
pub(crate) fn new(
start: Anchor,
end: Anchor,
version_map: VersionMap,
deletion_ts: DeletionTs,
) -> Self {
Deletion { start, end, version_map, deletion_ts }
}
#[inline]
pub(crate) fn no_op() -> Self {
Self::new(Anchor::zero(), Anchor::zero(), VersionMap::new(0, 0), 0)
}
#[inline(always)]
pub(crate) fn start(&self) -> Anchor {
self.start
}
#[inline(always)]
pub(crate) fn version_map(&self) -> &VersionMap {
&self.version_map
}
}
#[cfg(feature = "encode")]
mod encode {
use super::*;
use crate::encode::{Decode, Encode, IntDecodeError};
use crate::version_map::encode::BaseMapDecodeError;
impl Encode for Deletion {
#[inline]
fn encode(&self, buf: &mut Vec<u8>) {
Anchors::new(&self.start, &self.end).encode(buf);
self.version_map.encode(buf);
self.deletion_ts.encode(buf);
}
}
pub(crate) enum DeletionDecodeError {
Anchors(AnchorsDecodeError),
Int(IntDecodeError),
VersionMap(BaseMapDecodeError<Length>),
}
impl From<AnchorsDecodeError> for DeletionDecodeError {
#[inline(always)]
fn from(err: AnchorsDecodeError) -> Self {
Self::Anchors(err)
}
}
impl From<IntDecodeError> for DeletionDecodeError {
#[inline(always)]
fn from(err: IntDecodeError) -> Self {
Self::Int(err)
}
}
impl From<BaseMapDecodeError<Length>> for DeletionDecodeError {
#[inline(always)]
fn from(err: BaseMapDecodeError<Length>) -> Self {
Self::VersionMap(err)
}
}
impl core::fmt::Display for DeletionDecodeError {
#[inline]
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
let err: &dyn core::fmt::Display = match self {
Self::Anchors(err) => err,
Self::Int(err) => err,
Self::VersionMap(err) => err,
};
write!(f, "Deletion couldn't be decoded: {err}")
}
}
impl Decode for Deletion {
type Value = Self;
type Error = DeletionDecodeError;
#[inline]
fn decode(buf: &[u8]) -> Result<(Self, &[u8]), Self::Error> {
let ((start, end), buf) = Anchors::decode(buf)?;
let (version_map, buf) = VersionMap::decode(buf)?;
let (deletion_ts, buf) = DeletionTs::decode(buf)?;
let this = Self::new(start, end, version_map, deletion_ts);
Ok((this, buf))
}
}
#[allow(dead_code)]
struct Anchors<'a> {
start: &'a InnerAnchor,
end: &'a InnerAnchor,
}
impl<'a> Anchors<'a> {
#[inline]
fn new(start: &'a InnerAnchor, end: &'a InnerAnchor) -> Self {
Self { start, end }
}
}
impl Encode for Anchors<'_> {
#[inline]
fn encode(&self, buf: &mut Vec<u8>) {
let flag = AnchorsFlag::from_anchors(self);
flag.encode(buf);
match flag {
AnchorsFlag::DifferentReplicaIds => {
self.start.encode(buf);
self.end.encode(buf);
},
AnchorsFlag::SameReplicaId => {
self.start.replica_id().encode(buf);
self.start.run_ts().encode(buf);
self.start.offset().encode(buf);
self.end.run_ts().encode(buf);
self.end.offset().encode(buf);
},
AnchorsFlag::SameReplicaIdAndRunTs => {
self.start.replica_id().encode(buf);
self.start.run_ts().encode(buf);
self.start.offset().encode(buf);
let length = self.end.offset() - self.start.offset();
length.encode(buf);
},
}
}
}
pub(crate) enum AnchorsDecodeError {
Int(IntDecodeError),
Flag(AnchorsFlagDecodeError),
}
impl From<IntDecodeError> for AnchorsDecodeError {
#[inline(always)]
fn from(err: IntDecodeError) -> Self {
Self::Int(err)
}
}
impl From<AnchorsFlagDecodeError> for AnchorsDecodeError {
#[inline(always)]
fn from(err: AnchorsFlagDecodeError) -> Self {
Self::Flag(err)
}
}
impl core::fmt::Display for AnchorsDecodeError {
#[inline]
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
let err: &dyn core::fmt::Display = match self {
Self::Int(err) => err,
Self::Flag(err) => err,
};
write!(f, "Anchors couldn't be decoded: {err}")
}
}
impl Decode for Anchors<'_> {
type Value = (Anchor, Anchor);
type Error = AnchorsDecodeError;
#[inline]
fn decode(buf: &[u8]) -> Result<(Self::Value, &[u8]), Self::Error> {
let (flag, buf) = AnchorsFlag::decode(buf)?;
match flag {
AnchorsFlag::DifferentReplicaIds => {
let (start, buf) = InnerAnchor::decode(buf)?;
let (end, buf) = InnerAnchor::decode(buf)?;
Ok(((start, end), buf))
},
AnchorsFlag::SameReplicaId => {
let (replica_id, buf) = ReplicaId::decode(buf)?;
let (start_run_ts, buf) = RunTs::decode(buf)?;
let (start_offset, buf) = Length::decode(buf)?;
let (end_run_ts, buf) = RunTs::decode(buf)?;
let (end_offset, buf) = Length::decode(buf)?;
let start = InnerAnchor::new(
replica_id,
start_offset,
start_run_ts,
);
let end =
InnerAnchor::new(replica_id, end_offset, end_run_ts);
Ok(((start, end), buf))
},
AnchorsFlag::SameReplicaIdAndRunTs => {
let (replica_id, buf) = ReplicaId::decode(buf)?;
let (run_ts, buf) = RunTs::decode(buf)?;
let (offset, buf) = Length::decode(buf)?;
let (length, buf) = Length::decode(buf)?;
let start = InnerAnchor::new(replica_id, offset, run_ts);
let end =
InnerAnchor::new(replica_id, offset + length, run_ts);
Ok(((start, end), buf))
},
}
}
}
enum AnchorsFlag {
SameReplicaId,
SameReplicaIdAndRunTs,
DifferentReplicaIds,
}
impl AnchorsFlag {
#[inline(always)]
fn from_anchors(anchors: &Anchors) -> Self {
if anchors.start.replica_id() == anchors.end.replica_id() {
if anchors.start.run_ts() == anchors.end.run_ts() {
Self::SameReplicaIdAndRunTs
} else {
Self::SameReplicaId
}
} else {
Self::DifferentReplicaIds
}
}
}
impl Encode for AnchorsFlag {
#[inline]
fn encode(&self, buf: &mut Vec<u8>) {
let flag: u8 = match self {
Self::DifferentReplicaIds => 0,
Self::SameReplicaId => 1,
Self::SameReplicaIdAndRunTs => 2,
};
buf.push(flag);
}
}
pub(crate) enum AnchorsFlagDecodeError {
EmptyBuffer,
InvalidByte(u8),
}
impl core::fmt::Display for AnchorsFlagDecodeError {
#[inline]
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
match self {
Self::EmptyBuffer => write!(
f,
"AnchorsFlag can't be decoded from an empty buffer"
),
Self::InvalidByte(byte) => write!(
f,
"AnchorsFlag can't be decoded from {byte}, it must be 0, \
1, or 2",
),
}
}
}
impl Decode for AnchorsFlag {
type Value = Self;
type Error = AnchorsFlagDecodeError;
#[inline]
fn decode(buf: &[u8]) -> Result<(Self::Value, &[u8]), Self::Error> {
let (&flag, buf) = buf
.split_first()
.ok_or(AnchorsFlagDecodeError::EmptyBuffer)?;
let this = match flag {
0 => Self::DifferentReplicaIds,
1 => Self::SameReplicaId,
2 => Self::SameReplicaIdAndRunTs,
_ => return Err(AnchorsFlagDecodeError::InvalidByte(flag)),
};
Ok((this, buf))
}
}
}
#[cfg(feature = "serde")]
mod serde {
crate::encode::impl_serialize!(super::Deletion);
crate::encode::impl_deserialize!(super::Deletion);
}