database: move Pod bound from Table -> Key (#61)

* database: use `Infallible` for non-dup secondary keys

* database: move `Pod` bound from `Table` -> `Key`

* pod: impl `DupKey<P, S>` where `{P, S}: Pod`

* pod: remove `DupKey` impl

* key: `DupKey`: remove `Key` bound, return `self.primary`

* pod: remove `Sealed` impl on `DupKey`

* pod: impl `Pod` for `std::convert::Infallible`
This commit is contained in:
hinto-janai 2024-02-13 17:21:10 -05:00 committed by GitHub
parent ce3c8c5870
commit 9f939c883c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 69 additions and 18 deletions

View file

@ -4,6 +4,8 @@
#[allow(unused_imports)] // docs #[allow(unused_imports)] // docs
use crate::table::Table; use crate::table::Table;
use crate::pod::Pod;
//---------------------------------------------------------------------------------------------------- Table //---------------------------------------------------------------------------------------------------- Table
/// Database [`Table`] key metadata. /// Database [`Table`] key metadata.
/// ///
@ -18,14 +20,28 @@ pub trait Key {
/// will just be the same type as [`Key::Primary`]. /// will just be the same type as [`Key::Primary`].
const DUPLICATE: bool; const DUPLICATE: bool;
/// The primary key type. // TODO: fix this sanakirja bound.
type Primary; cfg_if::cfg_if! {
if #[cfg(all(feature = "sanakirja", not(feature = "heed")))] {
/// The primary key type.
type Primary: Pod + sanakirja::Storable;
/// The secondary key type. /// The secondary key type.
/// ///
/// Only needs to be different than [`Key::Primary`] /// Only needs to be different than [`Key::Primary`]
/// if [`Key::DUPLICATE`] is `true`. /// if [`Key::DUPLICATE`] is `true`.
type Secondary; type Secondary: Pod + sanakirja::Storable;
} else {
/// The primary key type.
type Primary: Pod;
/// The secondary key type.
///
/// Only needs to be different than [`Key::Primary`]
/// if [`Key::DUPLICATE`] is `true`.
type Secondary: Pod;
}
}
/// Acquire [`Key::Primary`]. /// Acquire [`Key::Primary`].
fn primary(self) -> Self::Primary; fn primary(self) -> Self::Primary;
@ -105,23 +121,24 @@ impl_key! {
// Implement `Key` for any [`DupKey`] using [`Copy`] types. // Implement `Key` for any [`DupKey`] using [`Copy`] types.
impl<P, S> Key for DupKey<P, S> impl<P, S> Key for DupKey<P, S>
where where
P: Key + Copy, // TODO: fix sanakirja serde bound.
S: Key + Copy, P: Pod + Copy,
S: Pod + Copy,
{ {
const DUPLICATE: bool = true; const DUPLICATE: bool = true;
type Primary = Self; type Primary = P;
type Secondary = S; type Secondary = S;
#[inline] #[inline]
fn primary(self) -> Self::Primary { fn primary(self) -> Self::Primary {
self self.primary
} }
#[inline] #[inline]
fn primary_secondary(self) -> (Self::Primary, Self::Secondary) { fn primary_secondary(self) -> (Self::Primary, Self::Secondary) {
(self, self.secondary) (self.primary, self.secondary)
} }
} }

View file

@ -111,6 +111,7 @@ mod private {
impl<const N: usize> Sealed for [u8; N] {} impl<const N: usize> Sealed for [u8; N] {}
impl_sealed! { impl_sealed! {
std::convert::Infallible,
Vec<u8>, Vec<u8>,
Box<[u8]>, Box<[u8]>,
std::sync::Arc<[u8]>, std::sync::Arc<[u8]>,
@ -132,6 +133,42 @@ mod private {
} }
//---------------------------------------------------------------------------------------------------- Pod Impl (bytes) //---------------------------------------------------------------------------------------------------- Pod Impl (bytes)
// Implement for `Infallible`.
// This type is `!` and should never be constructable,
// so all these functions will just panic.
impl Pod for std::convert::Infallible {
#[cold]
#[inline(never)]
fn as_bytes(&self) -> impl AsRef<[u8]> {
let bytes: &[u8] = unreachable!();
bytes
}
#[cold]
#[inline(never)]
fn into_bytes(self) -> Cow<'static, [u8]> {
unreachable!()
}
#[cold]
#[inline(never)]
fn from_bytes(bytes: &[u8]) -> Self {
unreachable!()
}
#[cold]
#[inline(never)]
fn from_reader<R: Read>(reader: &mut R) -> Self {
unreachable!()
}
#[cold]
#[inline(never)]
fn to_writer<W: Write>(self, writer: &mut W) -> usize {
unreachable!()
}
}
// Implement for owned `Vec` bytes. // Implement for owned `Vec` bytes.
impl Pod for Vec<u8> { impl Pod for Vec<u8> {
#[inline] #[inline]

View file

@ -24,18 +24,15 @@ pub trait Table {
/// Whether the table's values are all the same size or not. /// Whether the table's values are all the same size or not.
const CONSTANT_SIZE: bool; const CONSTANT_SIZE: bool;
/// Primary key type.
type Key: Key;
// TODO: fix this sanakirja bound. // TODO: fix this sanakirja bound.
cfg_if::cfg_if! { cfg_if::cfg_if! {
if #[cfg(all(feature = "sanakirja", not(feature = "heed")))] { if #[cfg(all(feature = "sanakirja", not(feature = "heed")))] {
/// Primary key type.
type Key: Key + Pod + sanakirja::Storable;
/// Value type. /// Value type.
type Value: Pod + sanakirja::Storable; type Value: Pod + sanakirja::Storable;
} else { } else {
/// Primary key type.
type Key: Key + Pod;
/// Value type. /// Value type.
type Value: Pod; type Value: Pod;
} }