zino_orm/
value.rs

1use super::{Entity, QueryBuilder, Schema};
2use http::Uri;
3use std::{borrow::Cow, net::IpAddr, path::Path};
4use url::Url;
5use zino_core::{
6    Decimal, JsonValue, Map, Uuid,
7    datetime::{Date, DateTime, Time},
8    extension::JsonObjectExt,
9};
10
11/// A generic interface for converting into SQL values.
12pub trait IntoSqlValue {
13    /// Converts `self` to a SQL value.
14    fn into_sql_value(self) -> JsonValue;
15}
16
17macro_rules! impl_into_sql_value {
18    ($($Ty: ty),+ $(,)?) => {
19        $(
20            impl IntoSqlValue for $Ty {
21                #[inline]
22                fn into_sql_value(self) -> JsonValue {
23                    self.into()
24                }
25            }
26        )+
27    }
28}
29
30impl_into_sql_value!(
31    (),
32    bool,
33    u8,
34    u16,
35    u32,
36    u64,
37    usize,
38    i8,
39    i16,
40    i32,
41    i64,
42    isize,
43    f32,
44    f64,
45    &str,
46    String,
47    JsonValue,
48    Map,
49    Date,
50    Time,
51);
52
53impl IntoSqlValue for DateTime {
54    #[inline]
55    fn into_sql_value(self) -> JsonValue {
56        if cfg!(feature = "orm-postgres") {
57            self.to_string().into()
58        } else {
59            self.to_utc_timestamp().into()
60        }
61    }
62}
63
64impl IntoSqlValue for Decimal {
65    #[inline]
66    fn into_sql_value(self) -> JsonValue {
67        self.to_string().into()
68    }
69}
70
71impl IntoSqlValue for IpAddr {
72    #[inline]
73    fn into_sql_value(self) -> JsonValue {
74        self.to_string().into()
75    }
76}
77
78impl IntoSqlValue for Uuid {
79    #[inline]
80    fn into_sql_value(self) -> JsonValue {
81        self.to_string().into()
82    }
83}
84
85impl IntoSqlValue for &Path {
86    #[inline]
87    fn into_sql_value(self) -> JsonValue {
88        self.to_str().into()
89    }
90}
91
92impl IntoSqlValue for &Uri {
93    #[inline]
94    fn into_sql_value(self) -> JsonValue {
95        self.to_string().into()
96    }
97}
98
99impl IntoSqlValue for &Url {
100    #[inline]
101    fn into_sql_value(self) -> JsonValue {
102        self.as_str().into()
103    }
104}
105
106impl IntoSqlValue for Cow<'_, str> {
107    #[inline]
108    fn into_sql_value(self) -> JsonValue {
109        self.into()
110    }
111}
112
113impl<T: IntoSqlValue> IntoSqlValue for Option<T> {
114    #[inline]
115    fn into_sql_value(self) -> JsonValue {
116        self.map(|v| v.into_sql_value()).into()
117    }
118}
119
120impl<T: IntoSqlValue> IntoSqlValue for Vec<T> {
121    #[inline]
122    fn into_sql_value(self) -> JsonValue {
123        JsonValue::Array(self.into_iter().map(|v| v.into_sql_value()).collect())
124    }
125}
126
127impl<T: IntoSqlValue, const N: usize> IntoSqlValue for [T; N] {
128    #[inline]
129    fn into_sql_value(self) -> JsonValue {
130        JsonValue::Array(self.into_iter().map(|v| v.into_sql_value()).collect())
131    }
132}
133
134impl<T: Clone + IntoSqlValue> IntoSqlValue for &[T] {
135    #[inline]
136    fn into_sql_value(self) -> JsonValue {
137        JsonValue::Array(self.iter().map(|v| v.to_owned().into_sql_value()).collect())
138    }
139}
140
141impl<E: Entity + Schema> IntoSqlValue for QueryBuilder<E> {
142    #[inline]
143    fn into_sql_value(self) -> JsonValue {
144        Map::from_entry("$subquery", self.build_subquery()).into()
145    }
146}