pgx_pg_sys/submodules/
datum.rs1#[cfg(not(nightly))]
3use sptr::Strict;
4use std::ptr::NonNull;
5
6#[repr(C)]
19struct DatumBlob {
20 _data: [u8; 0],
21 _marker: core::marker::PhantomData<(*mut u8, core::marker::PhantomPinned)>,
22}
23
24#[repr(transparent)]
49#[derive(Debug, Copy, Clone, PartialEq)]
50pub struct Datum(*mut DatumBlob);
51
52impl Datum {
53 pub fn value(self) -> usize {
56 #[allow(unstable_name_collisions)]
57 self.0.addr()
58 }
59
60 pub fn is_null(self) -> bool {
62 self.0.is_null()
63 }
64
65 pub fn cast_mut_ptr<T>(self) -> *mut T {
68 #[allow(unstable_name_collisions)]
69 self.0.cast()
70 }
71}
72
73impl From<usize> for Datum {
74 fn from(val: usize) -> Datum {
75 #[allow(unstable_name_collisions)]
76 Datum(NonNull::<DatumBlob>::dangling().as_ptr().with_addr(val))
77 }
78}
79
80impl From<Datum> for usize {
81 fn from(val: Datum) -> usize {
82 #[allow(unstable_name_collisions)]
83 val.0.addr()
84 }
85}
86
87impl From<isize> for Datum {
88 fn from(val: isize) -> Datum {
89 Datum::from(val as usize)
90 }
91}
92
93impl From<u8> for Datum {
94 fn from(val: u8) -> Datum {
95 Datum::from(usize::from(val))
96 }
97}
98
99impl From<u16> for Datum {
100 fn from(val: u16) -> Datum {
101 Datum::from(usize::from(val))
102 }
103}
104
105impl From<u32> for Datum {
106 fn from(val: u32) -> Datum {
107 Datum::from(val as usize)
108 }
109}
110
111impl From<u64> for Datum {
112 fn from(val: u64) -> Datum {
113 Datum::from(val as usize)
114 }
115}
116
117impl From<i8> for Datum {
118 fn from(val: i8) -> Datum {
119 Datum::from(isize::from(val))
120 }
121}
122
123impl From<i16> for Datum {
124 fn from(val: i16) -> Datum {
125 Datum::from(isize::from(val))
126 }
127}
128
129impl From<i32> for Datum {
130 fn from(val: i32) -> Datum {
131 Datum::from(val as usize)
132 }
133}
134
135impl From<i64> for Datum {
136 fn from(val: i64) -> Datum {
137 Datum::from(val as usize)
138 }
139}
140
141impl From<bool> for Datum {
142 fn from(val: bool) -> Datum {
143 Datum::from(val as usize)
144 }
145}
146
147impl<T> From<*mut T> for Datum {
148 fn from(val: *mut T) -> Datum {
149 Datum(val.cast())
150 }
151}
152
153impl<T> From<*const T> for Datum {
154 fn from(val: *const T) -> Datum {
155 Datum(val as *mut _)
156 }
157}
158
159impl<T> PartialEq<*mut T> for Datum {
160 fn eq(&self, other: &*mut T) -> bool {
161 &self.0.cast() == other
162 }
163}
164
165impl<T> PartialEq<Datum> for *mut T {
166 fn eq(&self, other: &Datum) -> bool {
167 self == &other.0.cast()
168 }
169}
170
171#[repr(C)]
175#[derive(Debug, Copy, Clone)]
176pub struct NullableDatum {
177 pub value: Datum,
178 pub isnull: bool,
179}
180
181impl TryFrom<NullableDatum> for Datum {
182 type Error = ();
183
184 fn try_from(nd: NullableDatum) -> Result<Datum, ()> {
185 let NullableDatum { value, isnull } = nd;
186 if isnull {
187 Err(())
188 } else {
189 Ok(value)
190 }
191 }
192}
193
194impl From<NullableDatum> for Option<Datum> {
195 fn from(nd: NullableDatum) -> Option<Datum> {
196 Some(Datum::try_from(nd).ok()?)
197 }
198}
199
200#[cfg(test)]
201mod test {
202 use super::*;
203
204 #[test]
205 fn roundtrip_integers() {
206 #[cfg(target_pointer_width = "64")]
207 mod types {
208 pub type UnsignedInt = u64;
209 pub type SignedInt = i64;
210 }
211 #[cfg(target_pointer_width = "32")]
212 mod types {
213 pub type UnsignedInt = u32;
215 pub type SignedInt = i32;
216 }
217 use types::*;
218
219 let val: SignedInt = 123456;
220 let datum = Datum::from(val);
221 assert_eq!(datum.value() as SignedInt, val);
222
223 let val: isize = 123456;
224 let datum = Datum::from(val);
225 assert_eq!(datum.value() as isize, val);
226
227 let val: SignedInt = -123456;
228 let datum = Datum::from(val);
229 assert_eq!(datum.value() as SignedInt, val);
230
231 let val: isize = -123456;
232 let datum = Datum::from(val);
233 assert_eq!(datum.value() as isize, val);
234
235 let val: UnsignedInt = 123456;
236 let datum = Datum::from(val);
237 assert_eq!(datum.value() as UnsignedInt, val);
238
239 let val: usize = 123456;
240 let datum = Datum::from(val);
241 assert_eq!(datum.value() as usize, val);
242 }
243}