sqlx_exasol/types/
text.rs

1use std::fmt::Display;
2
3use sqlx_core::{
4    decode::Decode,
5    encode::{Encode, IsNull},
6    error::BoxDynError,
7    types::{Text, Type},
8};
9
10use crate::{arguments::ExaBuffer, ExaTypeInfo, ExaValueRef, Exasol};
11
12impl<T> Type<Exasol> for Text<T> {
13    fn type_info() -> ExaTypeInfo {
14        <String as Type<Exasol>>::type_info()
15    }
16
17    fn compatible(ty: &ExaTypeInfo) -> bool {
18        <String as Type<Exasol>>::compatible(ty)
19    }
20}
21
22impl<'q, T> Encode<'q, Exasol> for Text<T>
23where
24    T: Display,
25{
26    fn encode_by_ref(&self, buf: &mut ExaBuffer) -> Result<IsNull, BoxDynError> {
27        let prev_len = buf.buffer.len();
28        buf.append(format_args!("{}", self.0))?;
29
30        // Serializing an empty string would result in just the quotes being added to the buffer.
31        // Important because Exasol treats empty strings as NULL.
32        if buf.buffer.len() - prev_len == 2 {
33            Ok(IsNull::Yes)
34        } else {
35            // Otherwise, the resulted text was not an empty string.
36            Ok(IsNull::No)
37        }
38    }
39}
40
41impl<'r, T> Decode<'r, Exasol> for Text<T>
42where
43    for<'a> T: TryFrom<&'a str>,
44    for<'a> BoxDynError: From<<T as TryFrom<&'a str>>::Error>,
45{
46    fn decode(value: ExaValueRef<'r>) -> Result<Self, BoxDynError> {
47        let s: &str = Decode::<Exasol>::decode(value)?;
48        Ok(Self(s.try_into()?))
49    }
50}
51
52#[cfg(test)]
53mod tests {
54    use sqlx::{types::Text, Encode};
55
56    use crate::ExaArguments;
57
58    #[test]
59    fn test_text_null_string() {
60        let mut arg_buffer = ExaArguments::default();
61        let is_null = Text(String::new())
62            .encode_by_ref(&mut arg_buffer.buf)
63            .unwrap();
64
65        assert!(is_null.is_null());
66    }
67
68    #[test]
69    fn test_text_null_str() {
70        let mut arg_buffer = ExaArguments::default();
71        let is_null = Text("").encode_by_ref(&mut arg_buffer.buf).unwrap();
72
73        assert!(is_null.is_null());
74    }
75
76    #[test]
77    fn test_text_non_null_string() {
78        let mut arg_buffer = ExaArguments::default();
79        let is_null = Text(String::from("something"))
80            .encode_by_ref(&mut arg_buffer.buf)
81            .unwrap();
82
83        assert!(!is_null.is_null());
84    }
85
86    #[test]
87    fn test_text_non_null_str() {
88        let mut arg_buffer = ExaArguments::default();
89        let is_null = Text("something")
90            .encode_by_ref(&mut arg_buffer.buf)
91            .unwrap();
92
93        assert!(!is_null.is_null());
94    }
95}