Skip to main content

elefant_client/types/
text.rs

1use crate::protocol::FieldDescription;
2use crate::types::{FromSqlBase, FromSqlBinary, FromSqlText, ToSql};
3use crate::PostgresType;
4use std::error::Error;
5
6impl<'a> FromSqlBase<'a> for &'a str {
7    fn accepts_postgres_type(oid: i32) -> bool {
8        oid == PostgresType::TEXT.oid
9            || oid == PostgresType::NAME.oid
10            || oid == PostgresType::VARCHAR.oid
11            || oid == PostgresType::BPCHAR.oid
12    }
13}
14
15impl<'a> FromSqlBinary<'a> for &'a str {
16    fn from_sql_binary(
17        raw: &'a [u8],
18        _field: &FieldDescription,
19    ) -> Result<Self, Box<dyn Error + Sync + Send>> {
20        Ok(std::str::from_utf8(raw)?)
21    }
22}
23
24impl<'a> FromSqlText<'a> for &'a str {
25    fn from_sql_text(
26        raw: &'a str,
27        _field: &FieldDescription,
28    ) -> Result<Self, Box<dyn Error + Sync + Send>> {
29        Ok(raw)
30    }
31}
32
33impl<'a> FromSqlBase<'a> for String {
34    fn accepts_postgres_type(oid: i32) -> bool {
35        oid == PostgresType::TEXT.oid
36            || oid == PostgresType::NAME.oid
37            || oid == PostgresType::VARCHAR.oid
38            || oid == PostgresType::BPCHAR.oid
39    }
40}
41
42impl<'a> FromSqlBinary<'a> for String {
43    fn from_sql_binary(
44        raw: &'a [u8],
45        _field: &FieldDescription,
46    ) -> Result<Self, Box<dyn Error + Sync + Send>> {
47        Ok(std::str::from_utf8(raw)?.to_string())
48    }
49}
50
51impl<'a> FromSqlText<'a> for String {
52    fn from_sql_text(
53        raw: &'a str,
54        _field: &FieldDescription,
55    ) -> Result<Self, Box<dyn Error + Sync + Send>> {
56        Ok(raw.to_string())
57    }
58}
59
60impl ToSql for String {
61    fn to_sql_binary(
62        &self,
63        target_buffer: &mut Vec<u8>,
64    ) -> Result<(), Box<dyn Error + Sync + Send>> {
65        target_buffer.extend_from_slice(self.as_bytes());
66        Ok(())
67    }
68}
69
70#[cfg(test)]
71mod tests {
72    #[cfg(feature = "tokio")]
73    mod tokio_connection {
74        use crate::test_helpers::get_settings;
75        use crate::tokio_connection::new_client;
76        use tokio::test;
77
78        #[test]
79        async fn test_text_types() {
80            let mut client = new_client(get_settings()).await.unwrap();
81
82            let s: &str = client.read_single_value("select 'hello'::text;", &[]).await;
83            assert_eq!(s, "hello");
84
85            let s: String = client
86                .read_single_value_dual_mode("select 'hello'::text")
87                .await;
88            assert_eq!(s, "hello");
89        }
90    }
91}