mssql_value_serializer/
wrappers.rs

1use std::{
2    borrow::Cow,
3    fmt::{self, Debug, Display, Formatter},
4    marker::PhantomData,
5    ops::Deref,
6    rc::Rc,
7    sync::Arc,
8};
9
10use crate::{SqlLiteralError, SqlServerLiteral, SqlServerLiteralForValueList};
11
12/// A wrapper type for any value implementing [`SqlServerLiteral`].
13///
14/// This type allows you to easily convert a value into one that implements both [`Display`] and [`serde::Serialize`], enabling SQL Server literal behavior.
15///
16/// # Examples
17///
18/// ```rust
19/// use mssql_value_serializer::SqlServerLiteralWrapper;
20///
21/// let needle = "Some text";
22///
23/// let mut sql = format!(
24///     "
25///         SELECT
26///             *
27///         FROM
28///             [TABLE]
29///         WHERE
30///             name = {value}
31///     ",
32///     value = SqlServerLiteralWrapper::new(needle)
33/// );
34///
35/// assert_eq!(
36///     "
37///         SELECT
38///             *
39///         FROM
40///             [TABLE]
41///         WHERE
42///             name = N'Some text'
43///     ",
44///     sql
45/// );
46/// ```
47#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
48pub struct SqlServerLiteralWrapper<T: SqlServerLiteral>(T);
49
50impl<T: SqlServerLiteral> SqlServerLiteralWrapper<T> {
51    #[inline]
52    pub const fn new(value: T) -> Self {
53        Self(value)
54    }
55
56    /// Consumes the wrapper and returns the inner value.
57    #[inline]
58    pub fn into_inner(self) -> T {
59        self.0
60    }
61}
62
63impl<T: SqlServerLiteral> Display for SqlServerLiteralWrapper<T> {
64    /// Formats the wrapped value as a SQL Server literal.
65    #[inline]
66    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
67        self.0.append_sql_literal_fmt(f).map_err(|_| fmt::Error)
68    }
69}
70
71impl<T: SqlServerLiteral> From<T> for SqlServerLiteralWrapper<T> {
72    #[inline]
73    fn from(value: T) -> Self {
74        Self::new(value)
75    }
76}
77
78impl<T: SqlServerLiteral> Deref for SqlServerLiteralWrapper<T> {
79    type Target = T;
80
81    #[inline]
82    fn deref(&self) -> &Self::Target {
83        &self.0
84    }
85}
86
87impl<T: SqlServerLiteral> SqlServerLiteral for SqlServerLiteralWrapper<T> {
88    #[inline]
89    fn append_sql_literal(&self, out: &mut String) -> Result<(), SqlLiteralError> {
90        self.0.append_sql_literal(out)
91    }
92
93    #[inline]
94    fn append_sql_literal_fmt(&self, out: &mut Formatter<'_>) -> Result<(), SqlLiteralError> {
95        self.0.append_sql_literal_fmt(out)
96    }
97}
98
99#[cfg(feature = "serde")]
100impl<T: SqlServerLiteral> serde::Serialize for SqlServerLiteralWrapper<T> {
101    #[inline]
102    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
103    where
104        S: serde::Serializer, {
105        let mut s = String::new();
106
107        self.0
108            .append_sql_literal(&mut s)
109            .map_err(|error| serde::ser::Error::custom(error.to_string()))?;
110
111        serializer.serialize_str(s.as_str())
112    }
113}
114
115/// A wrapper type that can hold either a borrowed or owned [`dyn SqlServerLiteral`] value.
116///
117/// This type allows generic code to handle both borrowed and owned SQL literal trait objects uniformly. It is primarily used when dynamically storing or formatting SQL literal values, without having to commit to a single ownership model.
118///
119/// # Examples
120///
121/// ```rust
122/// use mssql_value_serializer::{
123///     SqlServerLiteralDynWrapper, SqlServerLiteralForValueListWrapper,
124/// };
125///
126/// let s = String::from("Some text");
127///
128/// let mut values: Vec<SqlServerLiteralDynWrapper<'_>> = vec![
129///     SqlServerLiteralDynWrapper::from(1u8),
130///     SqlServerLiteralDynWrapper::from(2i8),
131///     SqlServerLiteralDynWrapper::from(&s),
132/// ];
133///
134/// let mut sql = format!(
135///     "
136///         SELECT
137///             *
138///         FROM
139///             [TABLE]
140///         WHERE
141///             name IN ({value})
142///     ",
143///     value = SqlServerLiteralForValueListWrapper::new(values)
144/// );
145///
146/// assert_eq!(
147///     "
148///         SELECT
149///             *
150///         FROM
151///             [TABLE]
152///         WHERE
153///             name IN (1, 2, N'Some text')
154///     ",
155///     sql
156/// );
157/// ```
158pub enum SqlServerLiteralDynWrapper<'a> {
159    Borrowed(&'a dyn SqlServerLiteral),
160    Owned(Box<dyn SqlServerLiteral>),
161}
162
163impl Debug for SqlServerLiteralDynWrapper<'_> {
164    /// Formats the wrapped value as a SQL Server literal.
165    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
166        struct SqlServerLiteralDynWrapperDebugFormatter<'a, T: SqlServerLiteral + ?Sized>(&'a T);
167
168        impl<'a, T: SqlServerLiteral + ?Sized> Debug for SqlServerLiteralDynWrapperDebugFormatter<'a, T> {
169            #[inline]
170            fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
171                self.0.append_sql_literal_fmt(f).map_err(|_| fmt::Error)
172            }
173        }
174
175        let (name, r) = match self {
176            Self::Borrowed(v) => ("Borrowed", *v),
177            Self::Owned(v) => ("Owned", v.as_ref()),
178        };
179
180        let mut debug = f.debug_tuple(name);
181
182        debug.field(&SqlServerLiteralDynWrapperDebugFormatter(r));
183
184        debug.finish()
185    }
186}
187
188impl Display for SqlServerLiteralDynWrapper<'_> {
189    /// Formats the wrapped value as a SQL Server literal.
190    #[inline]
191    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
192        match self {
193            Self::Borrowed(v) => v.append_sql_literal_fmt(f).map_err(|_| fmt::Error),
194            Self::Owned(v) => v.append_sql_literal_fmt(f).map_err(|_| fmt::Error),
195        }
196    }
197}
198
199impl From<Box<dyn SqlServerLiteral>> for SqlServerLiteralDynWrapper<'_> {
200    #[inline]
201    fn from(value: Box<dyn SqlServerLiteral>) -> Self {
202        Self::Owned(value)
203    }
204}
205
206impl<'a> From<&'a dyn SqlServerLiteral> for SqlServerLiteralDynWrapper<'a> {
207    #[inline]
208    fn from(value: &'a dyn SqlServerLiteral) -> Self {
209        Self::Borrowed(value)
210    }
211}
212
213impl<'a, T: ?Sized + ToOwned + SqlServerLiteral> From<&'a Cow<'a, T>>
214    for SqlServerLiteralDynWrapper<'a>
215where
216    T::Owned: SqlServerLiteral,
217    &'a T: SqlServerLiteral,
218{
219    #[inline]
220    fn from(value: &'a Cow<'a, T>) -> Self {
221        match value {
222            Cow::Owned(v) => Self::Borrowed(v),
223            Cow::Borrowed(v) => Self::Borrowed(v),
224        }
225    }
226}
227
228macro_rules! impl_dyn_wrapper {
229    ($ty:ty) => {
230        impl From<$ty> for $crate::SqlServerLiteralDynWrapper<'_> {
231            #[inline]
232            fn from(value: $ty) -> Self {
233                Self::Owned(Box::new(value))
234            }
235        }
236
237        impl<'a> From<&'a $ty> for $crate::SqlServerLiteralDynWrapper<'a> {
238            #[inline]
239            fn from(value: &'a $ty) -> Self {
240                Self::Borrowed(value)
241            }
242        }
243
244        impl<'a> From<::std::borrow::Cow<'a, $ty>> for $crate::SqlServerLiteralDynWrapper<'a> {
245            #[inline]
246            fn from(value: ::std::borrow::Cow<'a, $ty>) -> Self {
247                match value {
248                    ::std::borrow::Cow::Owned(v) => Self::Owned(Box::new(v)),
249                    ::std::borrow::Cow::Borrowed(v) => Self::Borrowed(v),
250                }
251            }
252        }
253    };
254    ($($ty:ty),+ $(,)*) => {
255        $(
256            $crate::impl_dyn_wrapper!($ty);
257        )+
258    };
259}
260
261macro_rules! impl_dyn_wrapper_slice {
262    ($ty:ty) => {
263        impl<'a> From<&'static $ty> for $crate::SqlServerLiteralDynWrapper<'a> {
264            #[inline]
265            fn from(value: &'static $ty) -> Self {
266                Self::Owned(Box::new(value))
267            }
268        }
269
270        impl<'a> From<&'a &'a $ty> for $crate::SqlServerLiteralDynWrapper<'a> {
271            #[inline]
272            fn from(value: &'a &'a $ty) -> Self {
273                Self::Borrowed(value)
274            }
275        }
276
277        impl<'a> From<::std::borrow::Cow<'a, $ty>> for $crate::SqlServerLiteralDynWrapper<'a> {
278            #[inline]
279            fn from(value: ::std::borrow::Cow<'a, $ty>) -> Self {
280                // match value {
281                //     Cow::Owned(v) => Self::Owned(Box::new(v)),
282                //     Cow::Borrowed(v) => Self::Borrowed(v as &'a dyn SqlServerLiteral), // We can't use trait object like this. I don't know why.
283                // }
284
285                let value = value.into_owned();
286
287                Self::Owned(Box::new(value))
288            }
289        }
290    };
291    ($($ty:ty),+ $(,)*) => {
292        $(
293            $crate::impl_dyn_wrapper_slice!($ty);
294        )+
295    };
296}
297
298pub(crate) use impl_dyn_wrapper;
299pub(crate) use impl_dyn_wrapper_slice;
300
301impl<'a> Deref for SqlServerLiteralDynWrapper<'a> {
302    type Target = dyn SqlServerLiteral + 'a;
303
304    #[inline]
305    fn deref(&self) -> &Self::Target {
306        match self {
307            Self::Owned(v) => v.as_ref(),
308            Self::Borrowed(v) => *v,
309        }
310    }
311}
312
313impl<'a> SqlServerLiteral for SqlServerLiteralDynWrapper<'a> {
314    #[inline]
315    fn append_sql_literal(&self, out: &mut String) -> Result<(), SqlLiteralError> {
316        self.deref().append_sql_literal(out)
317    }
318
319    #[inline]
320    fn append_sql_literal_fmt(&self, out: &mut Formatter<'_>) -> Result<(), SqlLiteralError> {
321        self.deref().append_sql_literal_fmt(out)
322    }
323}
324
325#[cfg(feature = "serde")]
326impl<'a> serde::Serialize for SqlServerLiteralDynWrapper<'a> {
327    #[inline]
328    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
329    where
330        S: serde::Serializer, {
331        let mut s = String::new();
332
333        self.deref()
334            .append_sql_literal(&mut s)
335            .map_err(|error| serde::ser::Error::custom(error.to_string()))?;
336
337        serializer.serialize_str(s.as_str())
338    }
339}
340
341struct SqlServerLiteralForValueListWrapperDebugFormatter<
342    'a,
343    T: SqlServerLiteralForValueList + ?Sized,
344>(&'a T);
345
346impl<'a, T: SqlServerLiteralForValueList + ?Sized> Debug
347    for SqlServerLiteralForValueListWrapperDebugFormatter<'a, T>
348{
349    #[inline]
350    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
351        self.0.append_sql_literal_for_value_list_fmt(f).map_err(|_| fmt::Error)
352    }
353}
354
355/// A wrapper type for any value implementing [`SqlServerLiteralForValueList`].
356///
357/// This type allows you to easily convert a value into one that implements both [`Display`] and [`serde::Serialize`], enabling it to exhibit SQL Server literal value list behavior.
358///
359/// # Examples
360///
361/// ```rust
362/// use mssql_value_serializer::{SqlServerLiteral, SqlServerLiteralForValueListWrapper};
363///
364/// let needles: &[&str] = &["Some text", "Foo", "Bar"];
365///
366/// let mut sql = format!(
367///     "
368///         SELECT
369///             *
370///         FROM
371///             [TABLE]
372///         WHERE
373///             name IN ({value})
374///     ",
375///     value = SqlServerLiteralForValueListWrapper::new(needles)
376/// );
377///
378/// assert_eq!(
379///     "
380///         SELECT
381///             *
382///         FROM
383///             [TABLE]
384///         WHERE
385///             name IN (N'Some text', N'Foo', N'Bar')
386///     ",
387///     sql
388/// );
389pub struct SqlServerLiteralForValueListWrapper<T: SqlServerLiteralForValueList>(T);
390
391impl<T: SqlServerLiteralForValueList> SqlServerLiteralForValueListWrapper<T> {
392    #[inline]
393    pub const fn new(value: T) -> Self {
394        Self(value)
395    }
396
397    /// Consumes the wrapper and returns the inner value.
398    #[inline]
399    pub fn into_inner(self) -> T {
400        self.0
401    }
402}
403
404impl<T: SqlServerLiteralForValueList> Debug for SqlServerLiteralForValueListWrapper<T> {
405    #[inline]
406    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
407        let mut debug = f.debug_tuple("SqlServerLiteralForValueListWrapper");
408
409        debug.field(&SqlServerLiteralForValueListWrapperDebugFormatter(self));
410
411        debug.finish()
412    }
413}
414
415impl<T: SqlServerLiteralForValueList> Display for SqlServerLiteralForValueListWrapper<T> {
416    /// Formats the wrapped value as a SQL Server literal.
417    #[inline]
418    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
419        self.0.append_sql_literal_for_value_list_fmt(f).map_err(|_| fmt::Error)
420    }
421}
422
423impl<T: SqlServerLiteralForValueList> From<T> for SqlServerLiteralForValueListWrapper<T> {
424    #[inline]
425    fn from(value: T) -> Self {
426        Self::new(value)
427    }
428}
429
430impl<T: SqlServerLiteralForValueList> Deref for SqlServerLiteralForValueListWrapper<T> {
431    type Target = T;
432
433    #[inline]
434    fn deref(&self) -> &Self::Target {
435        &self.0
436    }
437}
438
439impl<T: SqlServerLiteralForValueList> SqlServerLiteralForValueList
440    for SqlServerLiteralForValueListWrapper<T>
441{
442    #[inline]
443    fn append_sql_literal_for_value_list(&self, out: &mut String) -> Result<(), SqlLiteralError> {
444        self.0.append_sql_literal_for_value_list(out)
445    }
446
447    #[inline]
448    fn append_sql_literal_for_value_list_fmt(
449        &self,
450        out: &mut Formatter<'_>,
451    ) -> Result<(), SqlLiteralError> {
452        self.0.append_sql_literal_for_value_list_fmt(out)
453    }
454}
455
456#[cfg(feature = "serde")]
457impl<T: SqlServerLiteralForValueList> serde::Serialize for SqlServerLiteralForValueListWrapper<T> {
458    #[inline]
459    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
460    where
461        S: serde::Serializer, {
462        let mut s = String::new();
463
464        self.0
465            .append_sql_literal_for_value_list(&mut s)
466            .map_err(|error| serde::ser::Error::custom(error.to_string()))?;
467
468        serializer.serialize_str(s.as_str())
469    }
470}
471
472/// A wrapper type for string values.
473///
474/// This type allows you to easily convert a value into one that implements both [`Display`] and [`serde::Serialize`], enabling SQL Server literal formatting for character strings (CHAR/VARCHAR) rather than Unicode character strings (NCHAR/NVARCHAR).
475///
476/// # Examples
477///
478/// ```rust
479/// use mssql_value_serializer::SqlServerCharWrapper;
480///
481/// let needle = "Some text";
482///
483/// let mut sql = format!(
484///     "
485///         SELECT
486///             *
487///         FROM
488///             [TABLE]
489///         WHERE
490///             name = {value}
491///     ",
492///     value = SqlServerCharWrapper::new(needle)
493/// );
494///
495/// assert_eq!(
496///     "
497///         SELECT
498///             *
499///         FROM
500///             [TABLE]
501///         WHERE
502///             name = 'Some text'
503///     ",
504///     sql
505/// );
506/// ```
507#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
508pub struct SqlServerCharWrapper<'a, T>(T, PhantomData<&'a ()>);
509
510impl<'a, T> SqlServerCharWrapper<'a, T> {
511    #[inline]
512    pub const fn new(value: T) -> Self {
513        Self(value, PhantomData)
514    }
515
516    /// Consumes the wrapper and returns the inner value.
517    #[inline]
518    pub fn into_inner(self) -> T {
519        self.0
520    }
521}
522
523impl<'a, T> Display for SqlServerCharWrapper<'a, T>
524where
525    SqlServerCharWrapper<'a, T>: SqlServerLiteral,
526{
527    /// Formats the wrapped value as a SQL Server character string literal.
528    #[inline]
529    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
530        self.append_sql_literal_fmt(f).map_err(|_| fmt::Error)
531    }
532}
533
534#[cfg(feature = "serde")]
535impl<'a, T> serde::Serialize for SqlServerCharWrapper<'a, T>
536where
537    SqlServerCharWrapper<'a, T>: SqlServerLiteral,
538{
539    #[inline]
540    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
541    where
542        S: serde::Serializer, {
543        let mut s = String::new();
544
545        self.append_sql_literal(&mut s)
546            .map_err(|error| serde::ser::Error::custom(error.to_string()))?;
547
548        serializer.serialize_str(s.as_str())
549    }
550}
551
552impl From<char> for SqlServerCharWrapper<'_, char> {
553    #[inline]
554    fn from(value: char) -> Self {
555        Self::new(value)
556    }
557}
558
559impl Deref for SqlServerCharWrapper<'_, char> {
560    type Target = char;
561
562    #[inline]
563    fn deref(&self) -> &Self::Target {
564        &self.0
565    }
566}
567
568impl SqlServerLiteral for SqlServerCharWrapper<'_, char> {
569    #[inline]
570    fn append_sql_literal(&self, out: &mut String) -> Result<(), SqlLiteralError> {
571        crate::push_string_literal_char(&self.0, out).unwrap();
572
573        Ok(())
574    }
575
576    #[inline]
577    fn append_sql_literal_fmt(&self, out: &mut Formatter<'_>) -> Result<(), SqlLiteralError> {
578        crate::push_string_literal_char(&self.0, out).unwrap();
579
580        Ok(())
581    }
582}
583
584macro_rules! impl_char_wrapper {
585    ($($ty:ty),+ $(,)*) => {
586        $(
587            impl<'a> From<$ty> for SqlServerCharWrapper<'a, $ty> {
588                #[inline]
589                fn from(value: $ty) -> Self {
590                    Self::new(value)
591                }
592            }
593
594            impl<'a> Deref for SqlServerCharWrapper<'a, $ty> {
595                type Target = str;
596
597                #[inline]
598                fn deref(&self) -> &Self::Target {
599                    &self.0
600                }
601            }
602
603            impl<'a> SqlServerLiteral for SqlServerCharWrapper<'a, $ty> {
604                #[inline]
605                fn append_sql_literal(&self, out: &mut String) -> Result<(), SqlLiteralError> {
606                    $crate::push_string_literal(&self.0, out).unwrap();
607
608                    Ok(())
609                }
610
611                #[inline]
612                fn append_sql_literal_fmt(&self, out: &mut Formatter<'_>) -> Result<(), SqlLiteralError> {
613                    $crate::push_string_literal(&self.0, out).unwrap();
614
615                    Ok(())
616                }
617            }
618        )+
619    };
620}
621impl_char_wrapper!(&'a str, String, Rc<String>, Arc<String>, Cow<'a, str>);