//! Database key abstraction; `trait Key`. //---------------------------------------------------------------------------------------------------- Import #[allow(unused_imports)] // docs use crate::table::Table; //---------------------------------------------------------------------------------------------------- Table /// Database [`Table`] key metadata. /// /// Purely compile time information for database table keys, supporting duplicate keys. pub trait Key { /// Does this [`Key`] require multiple keys to reach a value? /// /// If [`Key::DUPLICATE`] is `true`, [`Key::Secondary`] will contain /// the "subkey", or secondary key needed to access the actual value. /// /// If [`Key::DUPLICATE`] is `false`, [`Key::Secondary`] /// will just be the same type as [`Key::Primary`]. const DUPLICATE: bool; /// The primary key type. type Primary; /// The secondary key type. /// /// Only needs to be different than [`Key::Primary`] /// if [`Key::DUPLICATE`] is `true`. type Secondary; /// Acquire [`Key::Primary`]. fn primary(self) -> Self::Primary; /// Acquire [`Self::Primary`] & [`Self::Secondary`]. /// /// This only needs to be implemented on types that are [`Self::DUPLICATE`]. /// /// It is `unreachable!()` on non-duplicate key tables. fn primary_secondary(self) -> (Self::Primary, Self::Secondary); } /// Duplicate key container. /// /// This is a generic container to use alongside [`Key`] to support /// tables that require more than 1 key to access the value. #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr( feature = "borsh", derive(borsh::BorshSerialize, borsh::BorshDeserialize) )] pub struct DupKey
{
/// Primary key type.
pub primary: P,
/// Secondary key type.
pub secondary: S,
}
//---------------------------------------------------------------------------------------------------- Impl
/// Implement `Key` on most primitive types.
///
/// `Key::DUPLICATE` is always `false`.
macro_rules! impl_key {
(
$(
$t:ident // Key type.
),* $(,)?
) => {
$(
impl Key for $t {
const DUPLICATE: bool = false;
type Primary = $t;
// This 0 variant enum is unconstructable,
// and "has the same role as the ! “never” type":
// Key for DupKey
where
P: Key + Copy,
S: Key + Copy,
{
const DUPLICATE: bool = true;
type Primary = Self;
type Secondary = S;
#[inline]
fn primary(self) -> Self::Primary {
self
}
#[inline]
fn primary_secondary(self) -> (Self::Primary, Self::Secondary) {
(self, self.secondary)
}
}
//---------------------------------------------------------------------------------------------------- Tests
#[cfg(test)]
mod test {
// use super::*;
}