1use crate::arguments::XuguArgumentValue;
2use crate::protocol::text::{ColumnFlags, ColumnType};
3use crate::{Xugu, XuguTypeInfo, XuguValueRef};
4
5use sqlx_core::decode::Decode;
6use sqlx_core::encode::{Encode, IsNull};
7use sqlx_core::error::BoxDynError;
8use sqlx_core::types::Type;
9use sqlx_core::value::ValueRef;
10use std::borrow::Cow;
11
12impl Type<Xugu> for str {
13 fn type_info() -> XuguTypeInfo {
14 XuguTypeInfo {
15 r#type: ColumnType::CHAR,
16 flags: ColumnFlags::empty(),
17 }
18 }
19
20 fn compatible(ty: &XuguTypeInfo) -> bool {
21 matches!(
22 ty.r#type,
23 ColumnType::BLOB
24 | ColumnType::BLOB_I
25 | ColumnType::BLOB_M
26 | ColumnType::BLOB_OM
27 | ColumnType::BLOB_S
28 | ColumnType::CLOB
29 | ColumnType::BINARY
30 | ColumnType::NUMERIC
31 | ColumnType::TINYINT
32 | ColumnType::SMALLINT
33 | ColumnType::INTEGER
34 | ColumnType::BIGINT
35 | ColumnType::BOOLEAN
36 | ColumnType::CHAR
37 | ColumnType::NCHAR
38 | ColumnType::GUID
39 | ColumnType::ROWID
40 | ColumnType::ROWVERSION
41 | ColumnType::ARRAY
42 | ColumnType::VECTOR
43 | ColumnType::HALFVEC
44 | ColumnType::SPARSEVEC
45
46 | ColumnType::POINT
48 | ColumnType::LSEG
49 | ColumnType::PATH
50 | ColumnType::BOX
51 | ColumnType::POLYGON
52 | ColumnType::LINE
53 | ColumnType::CIRCLE
54 | ColumnType::GEOMETRY
55 | ColumnType::GEOGRAPHY
56 | ColumnType::BOX2D
57 | ColumnType::BOX3D
58 | ColumnType::SPHEROID
59 | ColumnType::RASTER
60 )
61 }
62}
63
64impl<'q> Encode<'q, Xugu> for &'q str {
65 fn encode_by_ref(&self, args: &mut Vec<XuguArgumentValue<'q>>) -> Result<IsNull, BoxDynError> {
66 args.push(XuguArgumentValue::Str(Cow::Borrowed(*self)));
67
68 Ok(IsNull::No)
69 }
70}
71
72impl<'q> Decode<'q, Xugu> for &'q str {
73 fn decode(value: XuguValueRef<'q>) -> Result<Self, BoxDynError> {
74 value.as_str()
75 }
76}
77
78impl Type<Xugu> for Box<str> {
79 fn type_info() -> XuguTypeInfo {
80 <&str as Type<Xugu>>::type_info()
81 }
82
83 fn compatible(ty: &XuguTypeInfo) -> bool {
84 <&str as Type<Xugu>>::compatible(ty)
85 }
86}
87
88impl Encode<'_, Xugu> for Box<str> {
89 fn encode(self, args: &mut Vec<XuguArgumentValue<'_>>) -> Result<IsNull, BoxDynError> {
90 args.push(XuguArgumentValue::Str(Cow::Owned(self.into_string())));
91
92 Ok(IsNull::No)
93 }
94
95 fn encode_by_ref(&self, args: &mut Vec<XuguArgumentValue<'_>>) -> Result<IsNull, BoxDynError> {
96 args.push(XuguArgumentValue::Str(Cow::Owned(
97 self.clone().into_string(),
98 )));
99
100 Ok(IsNull::No)
101 }
102}
103
104impl<'r> Decode<'r, Xugu> for Box<str> {
105 fn decode(value: XuguValueRef<'r>) -> Result<Self, BoxDynError> {
106 let ty = value.type_info().r#type;
107 if matches!(
108 ty,
109 ColumnType::TINYINT | ColumnType::SMALLINT | ColumnType::INTEGER | ColumnType::BIGINT
110 ) {
111 let num = <i64 as Decode<Xugu>>::decode(value)?;
112 return Ok(Box::from(num.to_string()));
113 }
114
115 value.as_str().map(Box::from)
116 }
117}
118
119impl Type<Xugu> for String {
120 fn type_info() -> XuguTypeInfo {
121 <str as Type<Xugu>>::type_info()
122 }
123
124 fn compatible(ty: &XuguTypeInfo) -> bool {
125 <str as Type<Xugu>>::compatible(ty)
126 }
127}
128
129impl Encode<'_, Xugu> for String {
130 fn encode(self, args: &mut Vec<XuguArgumentValue<'_>>) -> Result<IsNull, BoxDynError> {
131 args.push(XuguArgumentValue::Str(Cow::Owned(self)));
132
133 Ok(IsNull::No)
134 }
135
136 fn encode_by_ref(&self, args: &mut Vec<XuguArgumentValue<'_>>) -> Result<IsNull, BoxDynError> {
137 args.push(XuguArgumentValue::Str(Cow::Owned(self.clone())));
138
139 Ok(IsNull::No)
140 }
141}
142
143impl Decode<'_, Xugu> for String {
144 fn decode(value: XuguValueRef<'_>) -> Result<Self, BoxDynError> {
145 let ty = value.type_info().r#type;
146 if matches!(
147 ty,
148 ColumnType::TINYINT | ColumnType::SMALLINT | ColumnType::INTEGER | ColumnType::BIGINT
149 ) {
150 let num = <i64 as Decode<Xugu>>::decode(value)?;
151 return Ok(num.to_string());
152 }
153
154 value.as_str().map(ToOwned::to_owned)
155 }
156}
157
158impl Type<Xugu> for Cow<'_, str> {
159 fn type_info() -> XuguTypeInfo {
160 <&str as Type<Xugu>>::type_info()
161 }
162
163 fn compatible(ty: &XuguTypeInfo) -> bool {
164 <&str as Type<Xugu>>::compatible(ty)
165 }
166}
167
168impl<'q> Encode<'q, Xugu> for Cow<'q, str> {
169 fn encode(self, args: &mut Vec<XuguArgumentValue<'q>>) -> Result<IsNull, BoxDynError> {
170 args.push(XuguArgumentValue::Str(self));
171
172 Ok(IsNull::No)
173 }
174
175 fn encode_by_ref(&self, args: &mut Vec<XuguArgumentValue<'q>>) -> Result<IsNull, BoxDynError> {
176 args.push(XuguArgumentValue::Str(self.clone()));
177
178 Ok(IsNull::No)
179 }
180}
181
182impl<'r> Decode<'r, Xugu> for Cow<'r, str> {
183 fn decode(value: XuguValueRef<'r>) -> Result<Self, BoxDynError> {
184 let ty = value.type_info().r#type;
185 if matches!(
186 ty,
187 ColumnType::TINYINT | ColumnType::SMALLINT | ColumnType::INTEGER | ColumnType::BIGINT
188 ) {
189 let num = <i64 as Decode<Xugu>>::decode(value)?;
190 return Ok(Cow::Owned(num.to_string()));
191 }
192
193 value.as_str().map(Cow::Borrowed)
194 }
195}