willow-data-model 0.4.1

The core datatypes of Willow, an eventually consistent data store with improved distributed deletion.
Documentation
use crate::prelude::*;

/// A coordinatelike value represents a point in the [three-dimensional willow space](https://willowprotocol.org/specs/grouping-entries/index.html#D3Range) (within a given [namespace](https://willowprotocol.org/specs/data-model/index.html#namespace)).
///
/// This trait does not include the namespace id, because our implementation separates entry storage by namespace from the get-go.
pub trait Coordinatelike<const MCL: usize, const MCC: usize, const MPL: usize, S>:
    Keylike<MCL, MCC, MPL, S>
{
    /// Returns the [timestamp](https://willowprotocol.org/specs/data-model/index.html#entry_timestamp) of `self`.
    fn wdm_timestamp(&self) -> Timestamp;
}

impl<const MCL: usize, const MCC: usize, const MPL: usize, S> Keylike<MCL, MCC, MPL, S>
    for (S, Path<MCL, MCC, MPL>, Timestamp)
{
    fn wdm_subspace_id(&self) -> &S {
        &self.0
    }

    fn wdm_path(&self) -> &Path<MCL, MCC, MPL> {
        &self.1
    }
}

impl<const MCL: usize, const MCC: usize, const MPL: usize, S> Coordinatelike<MCL, MCC, MPL, S>
    for (S, Path<MCL, MCC, MPL>, Timestamp)
{
    fn wdm_timestamp(&self) -> Timestamp {
        self.2
    }
}

/// Methods for working with [`Coordinatelikes`](Coordinatelike).
///
/// This trait is automatically implemented by all types implementing [`Coordinatelike`].
pub trait CoordinatelikeExt<const MCL: usize, const MCC: usize, const MPL: usize, S>:
    Coordinatelike<MCL, MCC, MPL, S> + KeylikeExt<MCL, MCC, MPL, S>
{
    /// Returns whether `self` and `other` describe equal coordinates, i.e., whether their [subspace ids](Keylike::wdm_subspace_id), [paths](Keylike::wdm_path), and [timestamps](Coordinatelike::wdm_timestamp) are all equal.
    ///
    /// # Examples
    ///
    /// ```
    /// use willow_data_model::prelude::*;
    ///
    /// assert!(
    ///     ([7; 32], Path::<4, 4, 4>::new(), 25.into())
    ///     .wdm_coordinate_eq(&([7; 32], Path::<4, 4, 4>::new(), 25.into()))
    /// );
    /// assert!(
    ///     !([7; 32], Path::<4, 4, 4>::new(), 25.into())
    ///     .wdm_coordinate_eq(&([8; 32], Path::<4, 4, 4>::new(), 25.into()))
    /// );
    /// ```
    fn wdm_coordinate_eq<OtherCoordinate>(&self, other: &OtherCoordinate) -> bool
    where
        OtherCoordinate: Coordinatelike<MCL, MCC, MPL, S>,
        S: PartialEq,
    {
        self.wdm_key_eq(other) && self.wdm_timestamp() == other.wdm_timestamp()
    }

    /// Returns whether `self` and `other` describe non-equal coordinates, i.e., whether their [subspace ids](Keylike::wdm_subspace_id), [paths](Keylike::wdm_path), and [timestamps](Coordinatelike::wdm_timestamp) are not all equal.
    ///
    /// # Examples
    ///
    /// ```
    /// use willow_data_model::prelude::*;
    ///
    /// assert!(
    ///     !([7; 32], Path::<4, 4, 4>::new(), 25.into())
    ///     .wdm_coordinate_ne(&([7; 32], Path::<4, 4, 4>::new(), 25.into()))
    /// );
    /// assert!(
    ///     ([7; 32], Path::<4, 4, 4>::new(), 25.into())
    ///     .wdm_coordinate_ne(&([8; 32], Path::<4, 4, 4>::new(), 25.into()))
    /// );
    /// ```
    fn wdm_coordinate_ne<OtherCoordinate>(&self, other: &OtherCoordinate) -> bool
    where
        OtherCoordinate: Coordinatelike<MCL, MCC, MPL, S>,
        S: PartialEq,
    {
        self.wdm_key_ne(other) || self.wdm_timestamp() != other.wdm_timestamp()
    }

    /// Returns whether `self` is included in the given [`Grouping`].
    ///
    /// ```
    /// use willow_data_model::prelude::*;
    ///
    /// assert!(
    ///     ([7; 32], Path::<4, 4, 4>::new(), 8.into())
    ///     .wdm_is_in(
    ///         &Range3d::<4, 4, 4, [u8; 32]>::new([7; 32].., .., ..Timestamp::from(17))
    ///     )
    /// );
    /// assert!(
    ///     !([7; 32], Path::<4, 4, 4>::new(), 52.into())
    ///     .wdm_is_in(
    ///         &Range3d::<4, 4, 4, [u8; 32]>::new([7; 32].., .., ..Timestamp::from(17))
    ///     )
    /// );
    /// ```
    fn wdm_is_in<G>(&self, grouping: &G) -> bool
    where
        G: Grouping<MCL, MCC, MPL, S>,
    {
        grouping.wdm_includes(self)
    }

    /// Returns whether `self` is included in the intersection of the two given [`Groupings`](Grouping).
    ///
    /// ```
    /// use willow_data_model::prelude::*;
    ///
    /// assert!(
    ///     ([7; 32], Path::<4, 4, 4>::new(), 25.into())
    ///     .wdm_is_in_intersection(
    ///         &Range3d::<4, 4, 4, [u8; 32]>::new([7; 32].., .., Timestamp::from(17)..),
    ///         &Range3d::<4, 4, 4, [u8; 32]>::new([7; 32].., .., ..Timestamp::from(28)),
    ///     )
    /// );
    /// assert!(
    ///     !([7; 32], Path::<4, 4, 4>::new(), 30.into())
    ///     .wdm_is_in_intersection(
    ///         &Range3d::<4, 4, 4, [u8; 32]>::new([7; 32].., .., Timestamp::from(17)..),
    ///         &Range3d::<4, 4, 4, [u8; 32]>::new([7; 32].., .., ..Timestamp::from(28)),
    ///     )
    /// );
    /// assert!(
    ///     !([7; 32], Path::<4, 4, 4>::new(), 14.into())
    ///     .wdm_is_in_intersection(
    ///         &Range3d::<4, 4, 4, [u8; 32]>::new([7; 32].., .., Timestamp::from(17)..),
    ///         &Range3d::<4, 4, 4, [u8; 32]>::new([7; 32].., .., ..Timestamp::from(28)),
    ///     )
    /// );
    /// ```
    fn wdm_is_in_intersection<G>(&self, grouping1: &G, grouping2: &G) -> bool
    where
        G: Grouping<MCL, MCC, MPL, S>,
    {
        grouping1.wdm_includes_in_intersection(grouping2, self)
    }
}

impl<const MCL: usize, const MCC: usize, const MPL: usize, S, T> CoordinatelikeExt<MCL, MCC, MPL, S>
    for T
where
    T: Coordinatelike<MCL, MCC, MPL, S>,
{
}