mssql_value_serializer/literals/
mod.rs1#[cfg(feature = "bigdecimal")]
2mod bigdecimal;
3#[cfg(feature = "chrono")]
4mod chrono;
5#[cfg(feature = "num-bigint")]
6mod num_bigint;
7#[cfg(feature = "rust_decimal")]
8mod rust_decimal;
9#[cfg(feature = "time")]
10mod time;
11#[cfg(feature = "uuid")]
12mod uuid;
13
14use std::{
15 fmt::{self, Formatter, Write},
16 rc::Rc,
17 sync::Arc,
18};
19
20use crate::{
21 impl_dyn_wrapper, impl_dyn_wrapper_slice, SqlLiteralError, SqlServerLiteral,
22 SqlServerLiteralDynWrapper,
23};
24
25impl SqlServerLiteral for bool {
28 #[inline]
29 fn append_sql_literal(&self, out: &mut String) -> Result<(), SqlLiteralError> {
30 out.push(if *self { '1' } else { '0' });
31
32 Ok(())
33 }
34
35 #[inline]
36 fn append_sql_literal_fmt(&self, out: &mut Formatter<'_>) -> Result<(), SqlLiteralError> {
37 out.write_char(if *self { '1' } else { '0' }).unwrap();
38
39 Ok(())
40 }
41}
42
43impl_dyn_wrapper!(bool);
44
45macro_rules! impl_int {
48 ($($t:ty),* $(,)*) => {
49 $(
50 impl SqlServerLiteral for $t {
51 #[inline]
52 fn append_sql_literal(&self, out: &mut String) -> Result<(), SqlLiteralError> {
53 write!(out, "{}", *self).unwrap();
54
55 Ok(())
56 }
57
58 #[inline]
59 fn append_sql_literal_fmt(&self, out: &mut Formatter<'_>) -> Result<(), SqlLiteralError> {
60 write!(out, "{}", *self).unwrap();
61
62 Ok(())
63 }
64 }
65
66 impl_dyn_wrapper!($t);
67 )*
68 }
69}
70impl_int!(i8, i16, i32, i64, i128, isize, u8, u16, u32, u64, u128, usize);
71
72macro_rules! impl_float {
73 ($($t:ty),* $(,)?) => {
74 $(
75 impl SqlServerLiteral for $t {
76 #[inline]
77 fn append_sql_literal(&self, out: &mut String) -> Result<(), SqlLiteralError> {
78 if !self.is_finite() {
79 return Err(SqlLiteralError::FloatNotFinite);
80 }
81
82 write!(out, "{}", *self).unwrap();
83
84 Ok(())
85 }
86
87 #[inline]
88 fn append_sql_literal_fmt(&self, out: &mut Formatter<'_>) -> Result<(), SqlLiteralError> {
89 if !self.is_finite() {
90 return Err(SqlLiteralError::FloatNotFinite);
91 }
92
93 write!(out, "{}", *self).unwrap();
94
95 Ok(())
96 }
97 }
98
99 impl_dyn_wrapper!($t);
100 )*
101 }
102}
103impl_float!(f32, f64);
104
105pub(crate) fn push_string_literal_char(ch: &char, out: &mut impl Write) -> fmt::Result {
108 out.write_char('\'')?;
109
110 if *ch == '\'' {
111 out.write_char('\'')?;
112 }
113
114 out.write_char(*ch)?;
115
116 out.write_char('\'')?;
117
118 Ok(())
119}
120
121fn push_nstring_literal_char(ch: &char, out: &mut impl Write) -> fmt::Result {
122 out.write_str("N'")?;
123
124 if *ch == '\'' {
125 out.write_char('\'')?;
126 }
127
128 out.write_char(*ch)?;
129
130 out.write_char('\'')?;
131
132 Ok(())
133}
134
135impl SqlServerLiteral for char {
136 #[inline]
137 fn append_sql_literal(&self, out: &mut String) -> Result<(), SqlLiteralError> {
138 push_nstring_literal_char(self, out).unwrap();
139
140 Ok(())
141 }
142
143 #[inline]
144 fn append_sql_literal_fmt(&self, out: &mut Formatter<'_>) -> Result<(), SqlLiteralError> {
145 push_nstring_literal_char(self, out).unwrap();
146
147 Ok(())
148 }
149}
150
151impl_dyn_wrapper!(char);
152
153pub(crate) fn push_string_literal(s: &str, out: &mut impl Write) -> fmt::Result {
154 out.write_char('\'')?;
155
156 for ch in s.chars() {
157 if ch == '\'' {
158 out.write_char('\'')?;
159 }
160
161 out.write_char(ch)?;
162 }
163
164 out.write_char('\'')?;
165
166 Ok(())
167}
168
169fn push_nstring_literal(s: &str, out: &mut impl Write) -> fmt::Result {
170 out.write_str("N'")?;
171
172 for ch in s.chars() {
173 if ch == '\'' {
174 out.write_char('\'')?;
175 }
176
177 out.write_char(ch)?;
178 }
179
180 out.write_char('\'')?;
181
182 Ok(())
183}
184
185macro_rules! impl_string {
186 ($($t:ty),* $(,)*) => {
187 $(
188 impl SqlServerLiteral for $t {
189 #[inline]
190 fn append_sql_literal(&self, out: &mut String) -> Result<(), SqlLiteralError> {
191 push_nstring_literal(self, out).unwrap();
192
193 Ok(())
194 }
195
196 #[inline]
197 fn append_sql_literal_fmt(&self, out: &mut Formatter<'_>) -> Result<(), SqlLiteralError> {
198 push_nstring_literal(self, out).unwrap();
199
200 Ok(())
201 }
202 }
203 )*
204 };
205}
206impl_string!(str, &str, String, Rc<String>, Arc<String>);
207impl_dyn_wrapper_slice!(str);
208impl_dyn_wrapper!(String, Rc<String>, Arc<String>);
209
210fn push_hex_bytes(bytes: &[u8], out: &mut impl Write) -> fmt::Result {
213 if bytes.is_empty() {
214 return Err(fmt::Error);
215 }
216
217 out.write_str("0x")?;
218
219 for b in bytes {
220 write!(out, "{:02X}", b)?;
221 }
222
223 Ok(())
224}
225
226fn push_hex_bytes_to_string(bytes: &[u8], out: &mut String) -> fmt::Result {
227 if bytes.is_empty() {
228 return Err(fmt::Error);
229 }
230
231 out.push_str("0x");
232
233 let len = out.len();
234 let hex_len = bytes.len() * 2;
235
236 out.reserve(hex_len);
237
238 unsafe {
239 let v = out.as_mut_vec();
240
241 v.set_len(len + hex_len);
242
243 const_hex::encode_to_slice_upper(bytes, &mut v[len..]).unwrap(); }
245
246 Ok(())
247}
248
249macro_rules! impl_u8_array {
250 ($($t:ty),* $(,)*) => {
251 $(
252 impl SqlServerLiteral for $t {
253 #[inline]
254 fn append_sql_literal(&self, out: &mut String) -> Result<(), SqlLiteralError> {
255 push_hex_bytes_to_string(self, out).unwrap();
256
257 Ok(())
258 }
259
260 #[inline]
261 fn append_sql_literal_fmt(&self, out: &mut Formatter<'_>) -> Result<(), SqlLiteralError> {
262 push_hex_bytes(self, out).unwrap();
263
264 Ok(())
265 }
266 }
267 )*
268 };
269}
270impl_u8_array!([u8], &[u8], Vec<u8>);
271impl_dyn_wrapper_slice!([u8]);
272impl_dyn_wrapper!(Vec<u8>);
273
274impl<T: SqlServerLiteral> SqlServerLiteral for Option<T> {
277 #[inline]
278 fn append_sql_literal(&self, out: &mut String) -> Result<(), SqlLiteralError> {
279 match self {
280 Some(v) => v.append_sql_literal(out),
281 None => {
282 out.push_str("NULL");
283
284 Ok(())
285 },
286 }
287 }
288
289 #[inline]
290 fn append_sql_literal_fmt(&self, out: &mut Formatter<'_>) -> Result<(), SqlLiteralError> {
291 match self {
292 Some(v) => v.append_sql_literal_fmt(out),
293 None => {
294 out.write_str("NULL").unwrap();
295
296 Ok(())
297 },
298 }
299 }
300}
301
302impl<T: SqlServerLiteral + 'static> From<Option<T>> for SqlServerLiteralDynWrapper<'_> {
303 #[inline]
304 fn from(value: Option<T>) -> Self {
305 Self::Owned(Box::new(value))
306 }
307}
308
309impl<'a, T: ?Sized> From<&'a Option<&'a T>> for SqlServerLiteralDynWrapper<'a>
310where
311 &'a T: SqlServerLiteral,
312{
313 #[inline]
314 fn from(value: &'a Option<&'a T>) -> Self {
315 Self::Borrowed(value)
316 }
317}