Radish alpha
h
Radicle Heartwood Protocol & Stack
Radicle
Git (anonymous pull)
Log in to clone via SSH
Turn `Redactable` into a semilattice
Alexis Sellier committed 3 years ago
commit 01b7686659356abd60d71169cc54b05d80b238b6
parent 681a8c9374a5ff39be3f09a2d6475f0638fe3361
4 files changed +63 -10
modified radicle-cob/src/history/entry.rs
@@ -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,
modified radicle-crdt/src/lib.rs
@@ -6,6 +6,7 @@ pub mod lwwmap;
pub mod lwwreg;
pub mod lwwset;
pub mod ord;
+
pub mod redactable;
pub mod thread;

#[cfg(test)]
added radicle-crdt/src/redactable.rs
@@ -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);
+
    }
+
}
modified radicle-crdt/src/thread.rs
@@ -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 {