willow25 0.7.3

A ready-to-use implementation of the Willow specifications.
Documentation
use crate::prelude::{Path, SubspaceId};

/// A keylike value is one that can be used to uniquely identify an [Entry](https://willowprotocol.org/specs/data-model/index.html#Entry) within a [namespace](https://willowprotocol.org/specs/data-model/index.html#namespace)-specific [store](https://willowprotocol.org/specs/data-model/index.html#store).
///
/// A [subspace_id](https://willowprotocol.org/specs/data-model/index.html#entry_subspace_id) and a [path](https://willowprotocol.org/specs/data-model/index.html#entry_path) together uniquely identify an entry in a namespace, because between any two non-equal entries with of equal [subspace_id](https://willowprotocol.org/specs/data-model/index.html#entry_subspace_id), [path](https://willowprotocol.org/specs/data-model/index.html#entry_path), and [namespace_id](https://willowprotocol.org/specs/data-model/index.html#entry_namespace_id), one would overwrite the other.
pub trait Keylike {
    /// Returns the [subspace_id](https://willowprotocol.org/specs/data-model/index.html#entry_subspace_id) of `self`.
    fn subspace_id(&self) -> &SubspaceId;

    /// Returns the [path](https://willowprotocol.org/specs/data-model/index.html#entry_path) of `self`.
    fn path(&self) -> &Path;
}

impl Keylike for (SubspaceId, Path) {
    fn subspace_id(&self) -> &SubspaceId {
        &self.0
    }

    fn path(&self) -> &Path {
        &self.1
    }
}

impl Keylike for (Path, SubspaceId) {
    fn subspace_id(&self) -> &SubspaceId {
        &self.1
    }

    fn path(&self) -> &Path {
        &self.0
    }
}

/// Methods for working with [`Keylikes`](Keylike).
///
/// This trait is automatically implemented by all types implementing [`Keylike`].
pub trait KeylikeExt: Keylike {
    /// Returns whether `self` and `other` describe equal keys, i.e., whether their [subspace ids](Keylike::subspace_id) and [paths](Keylike::path) are both equal.
    ///
    /// # Examples
    ///
    /// ```
    /// use willow25::prelude::*;
    ///
    /// assert!(
    ///     (SubspaceId::from([0; SUBSPACE_ID_WIDTH]), path!(""))
    ///     .key_eq(&(SubspaceId::from([0; SUBSPACE_ID_WIDTH]), path!("")))
    /// );
    /// assert!(
    ///     !(SubspaceId::from([0; SUBSPACE_ID_WIDTH]), path!(""))
    ///     .key_eq(&(SubspaceId::from([1; SUBSPACE_ID_WIDTH]), path!("")))
    /// );
    /// assert!(
    ///     !(SubspaceId::from([0; SUBSPACE_ID_WIDTH]), path!(""))
    ///     .key_eq(&(SubspaceId::from([0; SUBSPACE_ID_WIDTH]), path!("/nope")))
    /// );
    /// ```
    fn key_eq<OtherKey>(&self, other: &OtherKey) -> bool
    where
        OtherKey: Keylike,
    {
        self.subspace_id() == other.subspace_id() && self.path() == other.path()
    }

    /// Returns whether `self` and `other` describe non-equal keys, i.e., whether their [subspace ids](Keylike::subspace_id) and [paths](Keylike::path) are not both equal.
    ///
    /// # Examples
    ///
    /// ```
    /// use willow25::prelude::*;
    ///
    /// assert!(
    ///     !(SubspaceId::from([0; SUBSPACE_ID_WIDTH]), path!(""))
    ///     .key_ne(&(SubspaceId::from([0; SUBSPACE_ID_WIDTH]), path!("")))
    /// );
    /// assert!(
    ///     (SubspaceId::from([0; SUBSPACE_ID_WIDTH]), path!(""))
    ///     .key_ne(&(SubspaceId::from([1; SUBSPACE_ID_WIDTH]), path!("")))
    /// );
    /// assert!(
    ///     (SubspaceId::from([0; SUBSPACE_ID_WIDTH]), path!(""))
    ///     .key_ne(&(SubspaceId::from([0; SUBSPACE_ID_WIDTH]), path!("/nope")))
    /// );
    /// ```
    fn key_ne<OtherKey>(&self, other: &OtherKey) -> bool
    where
        OtherKey: Keylike,
    {
        self.subspace_id() != other.subspace_id() || self.path() != other.path()
    }
}

impl<T> KeylikeExt for T where T: Keylike + ?Sized {}