pgdog_plugin/
string.rs

1use crate::bindings::PdStr;
2use std::{ops::Deref, os::raw::c_void, slice::from_raw_parts, str::from_utf8_unchecked};
3
4impl From<&str> for PdStr {
5    fn from(value: &str) -> Self {
6        PdStr {
7            data: value.as_ptr() as *mut c_void,
8            len: value.len(),
9        }
10    }
11}
12
13impl From<&String> for PdStr {
14    fn from(value: &String) -> Self {
15        PdStr {
16            data: value.as_ptr() as *mut c_void,
17            len: value.len(),
18        }
19    }
20}
21
22impl Deref for PdStr {
23    type Target = str;
24
25    fn deref(&self) -> &Self::Target {
26        unsafe {
27            let slice = from_raw_parts::<u8>(self.data as *mut u8, self.len);
28            from_utf8_unchecked(slice)
29        }
30    }
31}
32
33impl PartialEq for PdStr {
34    fn eq(&self, other: &Self) -> bool {
35        **self == **other
36    }
37}
38
39impl Default for PdStr {
40    fn default() -> Self {
41        Self {
42            len: 0,
43            data: "".as_ptr() as *mut c_void,
44        }
45    }
46}
47
48#[cfg(test)]
49mod test {
50    use super::*;
51
52    #[test]
53    fn test_pd_str() {
54        let s = "one_two_three";
55        let pd = PdStr::from(s);
56        assert_eq!(pd.deref(), "one_two_three");
57
58        let s = String::from("one_two");
59        let pd = PdStr::from(&s);
60        assert_eq!(pd.deref(), "one_two");
61        assert_eq!(&*pd, "one_two");
62    }
63}