elefant-client 0.1.0

A pure rust implementation of a postgres client that is independent of the executor runtime
Documentation
use crate::protocol::FieldDescription;
use crate::types::{FromSqlBase, FromSqlBinary, FromSqlText, ToSql};
use crate::PostgresType;
use std::error::Error;

impl<'a> FromSqlBase<'a> for &'a str {
    fn accepts_postgres_type(oid: i32) -> bool {
        oid == PostgresType::TEXT.oid
            || oid == PostgresType::NAME.oid
            || oid == PostgresType::VARCHAR.oid
            || oid == PostgresType::BPCHAR.oid
    }
}

impl<'a> FromSqlBinary<'a> for &'a str {
    fn from_sql_binary(
        raw: &'a [u8],
        _field: &FieldDescription,
    ) -> Result<Self, Box<dyn Error + Sync + Send>> {
        Ok(std::str::from_utf8(raw)?)
    }
}

impl<'a> FromSqlText<'a> for &'a str {
    fn from_sql_text(
        raw: &'a str,
        _field: &FieldDescription,
    ) -> Result<Self, Box<dyn Error + Sync + Send>> {
        Ok(raw)
    }
}

impl<'a> FromSqlBase<'a> for String {
    fn accepts_postgres_type(oid: i32) -> bool {
        oid == PostgresType::TEXT.oid
            || oid == PostgresType::NAME.oid
            || oid == PostgresType::VARCHAR.oid
            || oid == PostgresType::BPCHAR.oid
    }
}

impl<'a> FromSqlBinary<'a> for String {
    fn from_sql_binary(
        raw: &'a [u8],
        _field: &FieldDescription,
    ) -> Result<Self, Box<dyn Error + Sync + Send>> {
        Ok(std::str::from_utf8(raw)?.to_string())
    }
}

impl<'a> FromSqlText<'a> for String {
    fn from_sql_text(
        raw: &'a str,
        _field: &FieldDescription,
    ) -> Result<Self, Box<dyn Error + Sync + Send>> {
        Ok(raw.to_string())
    }
}

impl ToSql for String {
    fn to_sql_binary(
        &self,
        target_buffer: &mut Vec<u8>,
    ) -> Result<(), Box<dyn Error + Sync + Send>> {
        target_buffer.extend_from_slice(self.as_bytes());
        Ok(())
    }
}

#[cfg(test)]
mod tests {
    #[cfg(feature = "tokio")]
    mod tokio_connection {
        use crate::test_helpers::get_settings;
        use crate::tokio_connection::new_client;
        use tokio::test;

        #[test]
        async fn test_text_types() {
            let mut client = new_client(get_settings()).await.unwrap();

            let s: &str = client.read_single_value("select 'hello'::text;", &[]).await;
            assert_eq!(s, "hello");

            let s: String = client
                .read_single_value_dual_mode("select 'hello'::text")
                .await;
            assert_eq!(s, "hello");
        }
    }
}