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
use crate::table::Table;
use crate::pod::Pod;
//---------------------------------------------------------------------------------------------------- Table
/// Database [`Table`] key metadata.
///
@ -18,14 +20,28 @@ pub trait Key {
/// will just be the same type as [`Key::Primary`].
const DUPLICATE: bool;
// TODO: fix this sanakirja bound.
cfg_if::cfg_if! {
if #[cfg(all(feature = "sanakirja", not(feature = "heed")))] {
/// The primary key type.
type Primary;
type Primary: Pod + sanakirja::Storable;
/// The secondary key type.
///
/// Only needs to be different than [`Key::Primary`]
/// 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`].
fn primary(self) -> Self::Primary;
@ -105,23 +121,24 @@ impl_key! {
// Implement `Key` for any [`DupKey`] using [`Copy`] types.
impl<P, S> Key for DupKey<P, S>
where
P: Key + Copy,
S: Key + Copy,
// TODO: fix sanakirja serde bound.
P: Pod + Copy,
S: Pod + Copy,
{
const DUPLICATE: bool = true;
type Primary = Self;
type Primary = P;
type Secondary = S;
#[inline]
fn primary(self) -> Self::Primary {
self
self.primary
}
#[inline]
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_sealed! {
std::convert::Infallible,
Vec<u8>,
Box<[u8]>,
std::sync::Arc<[u8]>,
@ -132,6 +133,42 @@ mod private {
}
//---------------------------------------------------------------------------------------------------- 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.
impl Pod for Vec<u8> {
#[inline]

View file

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