Skip to main content

sqlx_xugu/types/
bytes.rs

1use crate::arguments::XuguArgumentValue;
2use crate::protocol::text::ColumnType;
3use crate::{Xugu, XuguTypeInfo, XuguValueRef};
4use sqlx_core::decode::Decode;
5use sqlx_core::encode::{Encode, IsNull};
6use sqlx_core::error::BoxDynError;
7use sqlx_core::types::Type;
8use std::borrow::Cow;
9
10impl Type<Xugu> for [u8] {
11    fn type_info() -> XuguTypeInfo {
12        XuguTypeInfo::binary(ColumnType::BLOB)
13    }
14
15    fn compatible(ty: &XuguTypeInfo) -> bool {
16        matches!(
17            ty.r#type,
18            ColumnType::BLOB
19                | ColumnType::BLOB_I
20                | ColumnType::BLOB_M
21                | ColumnType::BLOB_OM
22                | ColumnType::BLOB_S
23                | ColumnType::CHAR
24                | ColumnType::NCHAR
25                | ColumnType::CLOB
26                | ColumnType::BINARY
27                | ColumnType::GUID
28        )
29    }
30}
31
32impl<'q> Encode<'q, Xugu> for &'q [u8] {
33    fn encode_by_ref(&self, args: &mut Vec<XuguArgumentValue<'q>>) -> Result<IsNull, BoxDynError> {
34        if self.is_empty() {
35            args.push(XuguArgumentValue::Bin(Cow::Borrowed(b"\0")));
36        } else {
37            args.push(XuguArgumentValue::Bin(Cow::Borrowed(self)));
38        }
39
40        Ok(IsNull::No)
41    }
42}
43
44impl<'q> Decode<'q, Xugu> for &'q [u8] {
45    fn decode(value: XuguValueRef<'q>) -> Result<Self, BoxDynError> {
46        value.as_bytes().map(map_empty)
47    }
48}
49
50impl Type<Xugu> for Box<[u8]> {
51    fn type_info() -> XuguTypeInfo {
52        <&[u8] as Type<Xugu>>::type_info()
53    }
54
55    fn compatible(ty: &XuguTypeInfo) -> bool {
56        <&[u8] as Type<Xugu>>::compatible(ty)
57    }
58}
59
60impl Encode<'_, Xugu> for Box<[u8]> {
61    fn encode(self, args: &mut Vec<XuguArgumentValue<'_>>) -> Result<IsNull, BoxDynError> {
62        if self.is_empty() {
63            args.push(XuguArgumentValue::Bin(Cow::Borrowed(b"\0")));
64        } else {
65            args.push(XuguArgumentValue::Bin(Cow::Owned(self.into_vec())));
66        }
67
68        Ok(IsNull::No)
69    }
70
71    fn encode_by_ref(&self, args: &mut Vec<XuguArgumentValue<'_>>) -> Result<IsNull, BoxDynError> {
72        if self.is_empty() {
73            args.push(XuguArgumentValue::Bin(Cow::Borrowed(b"\0")));
74        } else {
75            args.push(XuguArgumentValue::Bin(Cow::Owned(self.clone().into_vec())));
76        }
77
78        Ok(IsNull::No)
79    }
80}
81
82impl<'r> Decode<'r, Xugu> for Box<[u8]> {
83    fn decode(value: XuguValueRef<'r>) -> Result<Self, BoxDynError> {
84        value.as_bytes().map(map_empty).map(Box::from)
85    }
86}
87
88impl Type<Xugu> for Vec<u8> {
89    fn type_info() -> XuguTypeInfo {
90        <[u8] as Type<Xugu>>::type_info()
91    }
92
93    fn compatible(ty: &XuguTypeInfo) -> bool {
94        <&[u8] as Type<Xugu>>::compatible(ty)
95    }
96}
97
98impl Encode<'_, Xugu> for Vec<u8> {
99    fn encode(self, args: &mut Vec<XuguArgumentValue<'_>>) -> Result<IsNull, BoxDynError> {
100        if self.is_empty() {
101            args.push(XuguArgumentValue::Bin(Cow::Borrowed(b"\0")));
102        } else {
103            args.push(XuguArgumentValue::Bin(Cow::Owned(self)));
104        }
105
106        Ok(IsNull::No)
107    }
108
109    fn encode_by_ref(&self, args: &mut Vec<XuguArgumentValue<'_>>) -> Result<IsNull, BoxDynError> {
110        if self.is_empty() {
111            args.push(XuguArgumentValue::Bin(Cow::Borrowed(b"\0")));
112        } else {
113            args.push(XuguArgumentValue::Bin(Cow::Owned(self.clone())));
114        }
115
116        Ok(IsNull::No)
117    }
118}
119
120impl Decode<'_, Xugu> for Vec<u8> {
121    fn decode(value: XuguValueRef<'_>) -> Result<Self, BoxDynError> {
122        value.as_bytes().map(map_empty).map(ToOwned::to_owned)
123    }
124}
125
126// 处理空字节
127fn map_empty(s: &[u8]) -> &[u8] {
128    if s == b"\0" {
129        return b"";
130    }
131    s
132}