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 static FAKE_OID: NonZeroU32 = NonZeroU32::new(42).unwrap();
59 Self {
60 raw_value,
61 type_oid_lookup: &FAKE_OID,
62 }
63 }
64
65 #[cfg(feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes")]
69 pub fn new(raw_value: &'a [u8], type_oid_lookup: &'a dyn TypeOidLookup) -> Self {
70 Self::new_internal(raw_value, type_oid_lookup)
71 }
72
73 pub(in crate::pg) fn new_internal(
74 raw_value: &'a [u8],
75 type_oid_lookup: &'a dyn TypeOidLookup,
76 ) -> Self {
77 Self {
78 raw_value,
79 type_oid_lookup,
80 }
81 }
82
83 pub fn as_bytes(&self) -> &[u8] {
85 self.raw_value
86 }
87
88 pub fn get_oid(&self) -> NonZeroU32 {
90 self.type_oid_lookup.lookup()
91 }
92
93 pub(crate) fn subslice(&self, range: Range<usize>) -> Self {
94 Self {
95 raw_value: &self.raw_value[range],
96 ..*self
97 }
98 }
99}