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 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 + 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}