use std::num::NonZeroU32;
use std::ops::Range;
#[derive(Clone, Copy)]
#[allow(missing_debug_implementations)]
#[cfg(feature = "postgres_backend")]
pub struct PgValue<'a> {
raw_value: &'a [u8],
type_oid_lookup: &'a dyn TypeOidLookup,
}
#[cfg_attr(
docsrs,
doc(cfg(feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes"))
)]
#[allow(unreachable_pub)]
pub trait TypeOidLookup {
fn lookup(&self) -> NonZeroU32;
}
impl<F> TypeOidLookup for F
where
F: Fn() -> NonZeroU32,
{
fn lookup(&self) -> NonZeroU32 {
(self)()
}
}
impl TypeOidLookup for PgValue<'_> {
fn lookup(&self) -> NonZeroU32 {
self.type_oid_lookup.lookup()
}
}
impl TypeOidLookup for NonZeroU32 {
fn lookup(&self) -> NonZeroU32 {
*self
}
}
impl<'a> PgValue<'a> {
#[cfg(test)]
pub(crate) fn for_test(raw_value: &'a [u8]) -> Self {
#[allow(unsafe_code)] static FAKE_OID: NonZeroU32 = unsafe {
NonZeroU32::new_unchecked(42)
};
Self {
raw_value,
type_oid_lookup: &FAKE_OID,
}
}
#[cfg(feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes")]
pub fn new(raw_value: &'a [u8], type_oid_lookup: &'a dyn TypeOidLookup) -> Self {
Self::new_internal(raw_value, type_oid_lookup)
}
pub(in crate::pg) fn new_internal(
raw_value: &'a [u8],
type_oid_lookup: &'a dyn TypeOidLookup,
) -> Self {
Self {
raw_value,
type_oid_lookup,
}
}
pub fn as_bytes(&self) -> &[u8] {
self.raw_value
}
pub fn get_oid(&self) -> NonZeroU32 {
self.type_oid_lookup.lookup()
}
pub(crate) fn subslice(&self, range: Range<usize>) -> Self {
Self {
raw_value: &self.raw_value[range],
..*self
}
}
}