pgrx_pg_sys/
cstr.rs

1use core::ffi;
2
3/// A trait for converting a thing into a `char *` that is allocated by Postgres' palloc
4pub trait AsPgCStr {
5    /// Consumes `self` and converts it into a Postgres-allocated `char *`
6    fn as_pg_cstr(self) -> *mut ffi::c_char;
7}
8
9impl<'a> AsPgCStr for &'a str {
10    fn as_pg_cstr(self) -> *mut ffi::c_char {
11        let self_bytes = self.as_bytes();
12        let pg_cstr = unsafe { crate::palloc0(self_bytes.len() + 1) as *mut u8 };
13        let slice = unsafe { std::slice::from_raw_parts_mut(pg_cstr, self_bytes.len()) };
14        slice.copy_from_slice(self_bytes);
15        pg_cstr as *mut ffi::c_char
16    }
17}
18
19impl<'a> AsPgCStr for Option<&'a str> {
20    fn as_pg_cstr(self) -> *mut ffi::c_char {
21        match self {
22            Some(s) => s.as_pg_cstr(),
23            None => std::ptr::null_mut(),
24        }
25    }
26}
27
28impl AsPgCStr for String {
29    fn as_pg_cstr(self) -> *mut ffi::c_char {
30        self.as_str().as_pg_cstr()
31    }
32}
33
34impl AsPgCStr for &String {
35    fn as_pg_cstr(self) -> *mut ffi::c_char {
36        self.as_str().as_pg_cstr()
37    }
38}
39
40impl AsPgCStr for Option<String> {
41    fn as_pg_cstr(self) -> *mut ffi::c_char {
42        match self {
43            Some(s) => s.as_pg_cstr(),
44            None => std::ptr::null_mut(),
45        }
46    }
47}
48
49impl AsPgCStr for Option<&String> {
50    fn as_pg_cstr(self) -> *mut ffi::c_char {
51        match self {
52            Some(s) => s.as_pg_cstr(),
53            None => std::ptr::null_mut(),
54        }
55    }
56}
57
58impl AsPgCStr for &Option<String> {
59    fn as_pg_cstr(self) -> *mut ffi::c_char {
60        match self {
61            Some(s) => s.as_pg_cstr(),
62            None => std::ptr::null_mut(),
63        }
64    }
65}