1use std::num::NonZeroU32;
2use std::ops::Range;
3
4#[derive(Clone, Copy)]
6#[allow(missing_debug_implementations)]
7#[cfg(feature = "postgres_backend")]
8pub struct PgValue<'a> {
9 raw_value: &'a [u8],
10 type_oid_lookup: &'a dyn TypeOidLookup,
11}
12
13#[cfg_attr(
25 docsrs,
26 doc(cfg(feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes"))
27)]
28#[allow(unreachable_pub)]
29pub trait TypeOidLookup {
30 fn lookup(&self) -> NonZeroU32;
32}
33
34impl<F> TypeOidLookup for F
35where
36 F: Fn() -> NonZeroU32,
37{
38 fn lookup(&self) -> NonZeroU32 {
39 (self)()
40 }
41}
42
43impl TypeOidLookup for PgValue<'_> {
44 fn lookup(&self) -> NonZeroU32 {
45 self.type_oid_lookup.lookup()
46 }
47}
48
49impl TypeOidLookup for NonZeroU32 {
50 fn lookup(&self) -> NonZeroU32 {
51 *self
52 }
53}
54
55impl<'a> PgValue<'a> {
56 #[cfg(test)]
57 pub(crate) fn for_test(raw_value: &'a [u8]) -> Self {
58 #[allow(unsafe_code)] static FAKE_OID: NonZeroU32 = unsafe {
60 NonZeroU32::new_unchecked(42)
62 };
63 Self {
64 raw_value,
65 type_oid_lookup: &FAKE_OID,
66 }
67 }
68
69 #[cfg(feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes")]
73 pub fn new(raw_value: &'a [u8], type_oid_lookup: &'a dyn TypeOidLookup) -> Self {
74 Self::new_internal(raw_value, type_oid_lookup)
75 }
76
77 pub(in crate::pg) fn new_internal(
78 raw_value: &'a [u8],
79 type_oid_lookup: &'a dyn TypeOidLookup,
80 ) -> Self {
81 Self {
82 raw_value,
83 type_oid_lookup,
84 }
85 }
86
87 pub fn as_bytes(&self) -> &[u8] {
89 self.raw_value
90 }
91
92 pub fn get_oid(&self) -> NonZeroU32 {
94 self.type_oid_lookup.lookup()
95 }
96
97 pub(crate) fn subslice(&self, range: Range<usize>) -> Self {
98 Self {
99 raw_value: &self.raw_value[range],
100 ..*self
101 }
102 }
103}