sqlx_xugu/types/
str.rs

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                // 几何类型 按字符串编解码
44                | 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}