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
43 | ColumnType::POINT
45 | ColumnType::LSEG
46 | ColumnType::PATH
47 | ColumnType::BOX
48 | ColumnType::POLYGON
49 | ColumnType::LINE
50 | ColumnType::CIRCLE
51 | ColumnType::GEOMETRY
52 | ColumnType::GEOGRAPHY
53 | ColumnType::BOX2D
54 | ColumnType::BOX3D
55 | ColumnType::SPHEROID
56 | ColumnType::RASTER
57 )
58 }
59}
60
61impl<'q> Encode<'q, Xugu> for &'q str {
62 fn encode_by_ref(&self, args: &mut Vec<XuguArgumentValue<'q>>) -> Result<IsNull, BoxDynError> {
63 args.push(XuguArgumentValue::Str(Cow::Borrowed(*self)));
64
65 Ok(IsNull::No)
66 }
67}
68
69impl<'q> Decode<'q, Xugu> for &'q str {
70 fn decode(value: XuguValueRef<'q>) -> Result<Self, BoxDynError> {
71 value.as_str()
72 }
73}
74
75impl Type<Xugu> for Box<str> {
76 fn type_info() -> XuguTypeInfo {
77 <&str as Type<Xugu>>::type_info()
78 }
79
80 fn compatible(ty: &XuguTypeInfo) -> bool {
81 <&str as Type<Xugu>>::compatible(ty)
82 }
83}
84
85impl Encode<'_, Xugu> for Box<str> {
86 fn encode(self, args: &mut Vec<XuguArgumentValue<'_>>) -> Result<IsNull, BoxDynError> {
87 args.push(XuguArgumentValue::Str(Cow::Owned(self.into_string())));
88
89 Ok(IsNull::No)
90 }
91
92 fn encode_by_ref(&self, args: &mut Vec<XuguArgumentValue<'_>>) -> Result<IsNull, BoxDynError> {
93 args.push(XuguArgumentValue::Str(Cow::Owned(
94 self.clone().into_string(),
95 )));
96
97 Ok(IsNull::No)
98 }
99}
100
101impl<'r> Decode<'r, Xugu> for Box<str> {
102 fn decode(value: XuguValueRef<'r>) -> Result<Self, BoxDynError> {
103 let ty = value.type_info().r#type;
104 if matches!(
105 ty,
106 ColumnType::TINYINT | ColumnType::SMALLINT | ColumnType::INTEGER | ColumnType::BIGINT
107 ) {
108 let num = <i64 as Decode<Xugu>>::decode(value)?;
109 return Ok(Box::from(num.to_string()));
110 }
111
112 value.as_str().map(Box::from)
113 }
114}
115
116impl Type<Xugu> for String {
117 fn type_info() -> XuguTypeInfo {
118 <str as Type<Xugu>>::type_info()
119 }
120
121 fn compatible(ty: &XuguTypeInfo) -> bool {
122 <str as Type<Xugu>>::compatible(ty)
123 }
124}
125
126impl Encode<'_, Xugu> for String {
127 fn encode(self, args: &mut Vec<XuguArgumentValue<'_>>) -> Result<IsNull, BoxDynError> {
128 args.push(XuguArgumentValue::Str(Cow::Owned(self)));
129
130 Ok(IsNull::No)
131 }
132
133 fn encode_by_ref(&self, args: &mut Vec<XuguArgumentValue<'_>>) -> Result<IsNull, BoxDynError> {
134 args.push(XuguArgumentValue::Str(Cow::Owned(self.clone())));
135
136 Ok(IsNull::No)
137 }
138}
139
140impl Decode<'_, Xugu> for String {
141 fn decode(value: XuguValueRef<'_>) -> Result<Self, BoxDynError> {
142 let ty = value.type_info().r#type;
143 if matches!(
144 ty,
145 ColumnType::TINYINT | ColumnType::SMALLINT | ColumnType::INTEGER | ColumnType::BIGINT
146 ) {
147 let num = <i64 as Decode<Xugu>>::decode(value)?;
148 return Ok(num.to_string());
149 }
150
151 value.as_str().map(ToOwned::to_owned)
152 }
153}
154
155impl Type<Xugu> for Cow<'_, str> {
156 fn type_info() -> XuguTypeInfo {
157 <&str as Type<Xugu>>::type_info()
158 }
159
160 fn compatible(ty: &XuguTypeInfo) -> bool {
161 <&str as Type<Xugu>>::compatible(ty)
162 }
163}
164
165impl<'q> Encode<'q, Xugu> for Cow<'q, str> {
166 fn encode(self, args: &mut Vec<XuguArgumentValue<'q>>) -> Result<IsNull, BoxDynError> {
167 args.push(XuguArgumentValue::Str(self));
168
169 Ok(IsNull::No)
170 }
171
172 fn encode_by_ref(&self, args: &mut Vec<XuguArgumentValue<'q>>) -> Result<IsNull, BoxDynError> {
173 args.push(XuguArgumentValue::Str(self.clone()));
174
175 Ok(IsNull::No)
176 }
177}
178
179impl<'r> Decode<'r, Xugu> for Cow<'r, str> {
180 fn decode(value: XuguValueRef<'r>) -> Result<Self, BoxDynError> {
181 let ty = value.type_info().r#type;
182 if matches!(
183 ty,
184 ColumnType::TINYINT | ColumnType::SMALLINT | ColumnType::INTEGER | ColumnType::BIGINT
185 ) {
186 let num = <i64 as Decode<Xugu>>::decode(value)?;
187 return Ok(Cow::Owned(num.to_string()));
188 }
189
190 value.as_str().map(Cow::Borrowed)
191 }
192}