Turn `Redactable` into a semilattice

Signed-off-by: Alexis Sellier <alexis@radicle.xyz>
This commit is contained in:
Alexis Sellier 2022-11-24 19:02:45 +01:00
parent 681a8c9374
commit 01b7686659
No known key found for this signature in database
4 changed files with 63 additions and 10 deletions

View File

@ -39,6 +39,7 @@ pub struct Entry {
/// The identifier for this entry
pub(super) id: EntryId,
/// The content-address for this entry's author.
/// TODO: This shouldn't be here?
pub(super) author: Option<Oid>,
/// The content-address for the resource this entry lives under.
pub(super) resource: Oid,

View File

@ -6,6 +6,7 @@ pub mod lwwmap;
pub mod lwwreg;
pub mod lwwset;
pub mod ord;
pub mod redactable;
pub mod thread;
#[cfg(test)]

View File

@ -0,0 +1,60 @@
use crate::Semilattice;
/// An object that can be either present or removed.
#[derive(Default, Debug, Clone, Copy, PartialEq, Eq)]
pub enum Redactable<T> {
/// When the object is present.
Present(T),
/// When the object has been removed.
#[default]
Redacted,
}
impl<T> From<Option<T>> for Redactable<T> {
fn from(option: Option<T>) -> Self {
match option {
Some(v) => Self::Present(v),
None => Self::Redacted,
}
}
}
impl<T: PartialOrd> Redactable<T> {
pub fn merge(&mut self, other: Self) {
match (&self, other) {
(Self::Redacted, _) => {}
(Self::Present(_), Self::Redacted) => {
*self = Self::Redacted;
}
(Self::Present(a), Self::Present(b)) => {
if &b > a {
*self = Self::Present(b);
}
}
}
}
}
impl<T: PartialOrd> Semilattice for Redactable<T> {
fn join(mut self, other: Self) -> Self {
self.merge(other);
self
}
}
#[cfg(test)]
mod test {
use quickcheck_macros::quickcheck;
use super::*;
use crate::test;
#[quickcheck]
fn prop_invariants(a: Option<u8>, b: Option<u8>, c: Option<u8>) {
let a = Redactable::from(a);
let b = Redactable::from(b);
let c = Redactable::from(c);
test::assert_laws(&a, &b, &c);
}
}

View File

@ -11,6 +11,7 @@ use radicle::hash;
use crate::clock::LClock;
use crate::lwwreg::LWWReg;
use crate::lwwset::LWWSet;
use crate::redactable::Redactable;
/// Identifies a change.
pub type ChangeId = radicle::hash::Digest;
@ -63,16 +64,6 @@ pub struct Envelope {
pub signature: Signature,
}
/// An object that can be either present or removed.
#[derive(Default, Debug, Clone, Copy, PartialEq, Eq)]
pub enum Redactable<T> {
/// When the object is present.
Present(T),
/// When the object has been removed.
#[default]
Redacted,
}
/// A comment on a discussion thread.
#[derive(Default, Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct Comment {