sqlx_exasol/types/
str.rs

1use std::borrow::Cow;
2
3use serde::Deserialize;
4use sqlx_core::{
5    decode::Decode,
6    encode::{Encode, IsNull},
7    error::BoxDynError,
8    types::Type,
9};
10
11use crate::{
12    arguments::ExaBuffer,
13    database::Exasol,
14    type_info::{Charset, ExaDataType, ExaTypeInfo, StringLike},
15    value::ExaValueRef,
16};
17
18impl Type<Exasol> for str {
19    fn type_info() -> ExaTypeInfo {
20        let string_like = StringLike::new(StringLike::MAX_VARCHAR_LEN, Charset::Utf8);
21        ExaDataType::Varchar(string_like).into()
22    }
23
24    fn compatible(ty: &ExaTypeInfo) -> bool {
25        <Self as Type<Exasol>>::type_info().compatible(ty)
26    }
27}
28
29impl Encode<'_, Exasol> for &'_ str {
30    fn encode_by_ref(&self, buf: &mut ExaBuffer) -> Result<IsNull, BoxDynError> {
31        // Exasol treats empty strings as NULL
32        if self.is_empty() {
33            buf.append(())?;
34            return Ok(IsNull::Yes);
35        }
36
37        buf.append(self)?;
38        Ok(IsNull::No)
39    }
40
41    fn produces(&self) -> Option<ExaTypeInfo> {
42        Some(<Self as Type<Exasol>>::type_info())
43    }
44
45    fn size_hint(&self) -> usize {
46        // 2 Quotes + length
47        2 + self.len()
48    }
49}
50
51impl<'r> Decode<'r, Exasol> for &'r str {
52    fn decode(value: ExaValueRef<'r>) -> Result<Self, BoxDynError> {
53        <&str>::deserialize(value.value).map_err(From::from)
54    }
55}
56
57impl Type<Exasol> for String {
58    fn type_info() -> ExaTypeInfo {
59        <str as Type<Exasol>>::type_info()
60    }
61
62    fn compatible(ty: &ExaTypeInfo) -> bool {
63        <str as Type<Exasol>>::compatible(ty)
64    }
65}
66
67impl Encode<'_, Exasol> for String {
68    fn encode_by_ref(&self, buf: &mut ExaBuffer) -> Result<IsNull, BoxDynError> {
69        <&str as Encode<Exasol>>::encode(&**self, buf)
70    }
71
72    fn produces(&self) -> Option<ExaTypeInfo> {
73        <&str as Encode<Exasol>>::produces(&&**self)
74    }
75
76    fn size_hint(&self) -> usize {
77        <&str as Encode<Exasol>>::size_hint(&&**self)
78    }
79}
80
81impl Decode<'_, Exasol> for String {
82    fn decode(value: ExaValueRef<'_>) -> Result<Self, BoxDynError> {
83        <&str as Decode<Exasol>>::decode(value).map(ToOwned::to_owned)
84    }
85}
86
87impl Type<Exasol> for Cow<'_, str> {
88    fn type_info() -> ExaTypeInfo {
89        <&str as Type<Exasol>>::type_info()
90    }
91
92    fn compatible(ty: &ExaTypeInfo) -> bool {
93        <&str as Type<Exasol>>::compatible(ty)
94    }
95}
96
97impl Encode<'_, Exasol> for Cow<'_, str> {
98    fn encode_by_ref(&self, buf: &mut ExaBuffer) -> Result<IsNull, BoxDynError> {
99        match self {
100            Cow::Borrowed(str) => <&str as Encode<Exasol>>::encode(*str, buf),
101            Cow::Owned(str) => <&str as Encode<Exasol>>::encode(&**str, buf),
102        }
103    }
104
105    fn produces(&self) -> Option<ExaTypeInfo> {
106        <&str as Encode<Exasol>>::produces(&&**self)
107    }
108
109    fn size_hint(&self) -> usize {
110        <&str as Encode<Exasol>>::size_hint(&&**self)
111    }
112}
113
114impl<'r> Decode<'r, Exasol> for Cow<'r, str> {
115    fn decode(value: ExaValueRef<'r>) -> Result<Self, BoxDynError> {
116        Cow::deserialize(value.value).map_err(From::from)
117    }
118}