elefant_client/types/
char.rs1use crate::protocol::FieldDescription;
2use crate::types::{FromSqlBase, FromSqlBinary, FromSqlText, ToSql};
3use crate::PostgresType;
4use std::error::Error;
5
6impl<'a> FromSqlBase<'a> for char {
7 fn accepts_postgres_type(oid: i32) -> bool {
8 oid == PostgresType::CHAR.oid || oid == PostgresType::BPCHAR.oid
9 }
10}
11
12impl<'a> FromSqlBinary<'a> for char {
13 fn from_sql_binary(
14 raw: &'a [u8],
15 field: &FieldDescription,
16 ) -> Result<Self, Box<dyn Error + Sync + Send>> {
17 if raw.len() != 1 {
18 return Err(format!("Invalid length for char. Expected 1 byte, got {} bytes instead. Error occurred when parsing field {:?}", raw.len(), field).into());
19 }
20
21 Ok(raw[0] as char)
22 }
23}
24
25impl<'a> FromSqlText<'a> for char {
26 fn from_sql_text(
27 raw: &'a str,
28 field: &FieldDescription,
29 ) -> Result<Self, Box<dyn Error + Sync + Send>> {
30 if raw.is_empty() {
31 return Ok('\0');
33 }
34 if raw.len() != 1 {
35 return Err(format!("Invalid length for char. Expected 1 byte, got {} bytes instead. Error occurred when parsing field {:?}", raw.len(), field).into());
36 }
37
38 Ok(raw.chars().next().unwrap())
39 }
40}
41
42impl ToSql for char {
43 fn to_sql_binary(
44 &self,
45 target_buffer: &mut Vec<u8>,
46 ) -> Result<(), Box<dyn Error + Sync + Send>> {
47 target_buffer.push(*self as u8);
48 Ok(())
49 }
50}
51
52#[cfg(test)]
53mod tests {
54 #[cfg(feature = "tokio")]
55 mod tokio_connection {
56 use crate::test_helpers::get_settings;
57 use crate::tokio_connection::new_client;
58 use tokio::test;
59
60 #[test]
61 async fn test_char_type() {
62 let mut client = new_client(get_settings()).await.unwrap();
63
64 let c: char = client
65 .read_single_value_dual_mode("select 'a'::\"char\"")
66 .await;
67 assert_eq!(c, 'a');
68
69 let c: char = client
70 .read_single_value("select $1::\"char\";", &[&'A'])
71 .await;
72 assert_eq!(c, 'A');
73 }
74 }
75}