1use bytes::Bytes;
4
5#[derive(Debug, Clone, PartialEq)]
10pub enum SqlValue {
11 Null,
13 Bool(bool),
15 TinyInt(u8),
17 SmallInt(i16),
19 Int(i32),
21 BigInt(i64),
23 Float(f32),
25 Double(f64),
27 String(String),
29 Binary(Bytes),
31 #[cfg(feature = "decimal")]
33 Decimal(rust_decimal::Decimal),
34 #[cfg(feature = "uuid")]
36 Uuid(uuid::Uuid),
37 #[cfg(feature = "chrono")]
39 Date(chrono::NaiveDate),
40 #[cfg(feature = "chrono")]
42 Time(chrono::NaiveTime),
43 #[cfg(feature = "chrono")]
45 DateTime(chrono::NaiveDateTime),
46 #[cfg(feature = "chrono")]
48 DateTimeOffset(chrono::DateTime<chrono::FixedOffset>),
49 #[cfg(feature = "json")]
51 Json(serde_json::Value),
52 Xml(String),
54}
55
56impl SqlValue {
57 #[must_use]
59 pub fn is_null(&self) -> bool {
60 matches!(self, Self::Null)
61 }
62
63 #[must_use]
65 pub fn as_bool(&self) -> Option<bool> {
66 match self {
67 Self::Bool(v) => Some(*v),
68 _ => None,
69 }
70 }
71
72 #[must_use]
74 pub fn as_i32(&self) -> Option<i32> {
75 match self {
76 Self::Int(v) => Some(*v),
77 Self::SmallInt(v) => Some(*v as i32),
78 Self::TinyInt(v) => Some(*v as i32),
79 _ => None,
80 }
81 }
82
83 #[must_use]
85 pub fn as_i64(&self) -> Option<i64> {
86 match self {
87 Self::BigInt(v) => Some(*v),
88 Self::Int(v) => Some(*v as i64),
89 Self::SmallInt(v) => Some(*v as i64),
90 Self::TinyInt(v) => Some(*v as i64),
91 _ => None,
92 }
93 }
94
95 #[must_use]
97 pub fn as_f64(&self) -> Option<f64> {
98 match self {
99 Self::Double(v) => Some(*v),
100 Self::Float(v) => Some(*v as f64),
101 _ => None,
102 }
103 }
104
105 #[must_use]
107 pub fn as_str(&self) -> Option<&str> {
108 match self {
109 Self::String(v) => Some(v),
110 Self::Xml(v) => Some(v),
111 _ => None,
112 }
113 }
114
115 #[must_use]
117 pub fn as_bytes(&self) -> Option<&[u8]> {
118 match self {
119 Self::Binary(v) => Some(v),
120 _ => None,
121 }
122 }
123
124 #[must_use]
126 pub fn type_name(&self) -> &'static str {
127 match self {
128 Self::Null => "NULL",
129 Self::Bool(_) => "BIT",
130 Self::TinyInt(_) => "TINYINT",
131 Self::SmallInt(_) => "SMALLINT",
132 Self::Int(_) => "INT",
133 Self::BigInt(_) => "BIGINT",
134 Self::Float(_) => "REAL",
135 Self::Double(_) => "FLOAT",
136 Self::String(_) => "NVARCHAR",
137 Self::Binary(_) => "VARBINARY",
138 #[cfg(feature = "decimal")]
139 Self::Decimal(_) => "DECIMAL",
140 #[cfg(feature = "uuid")]
141 Self::Uuid(_) => "UNIQUEIDENTIFIER",
142 #[cfg(feature = "chrono")]
143 Self::Date(_) => "DATE",
144 #[cfg(feature = "chrono")]
145 Self::Time(_) => "TIME",
146 #[cfg(feature = "chrono")]
147 Self::DateTime(_) => "DATETIME2",
148 #[cfg(feature = "chrono")]
149 Self::DateTimeOffset(_) => "DATETIMEOFFSET",
150 #[cfg(feature = "json")]
151 Self::Json(_) => "JSON",
152 Self::Xml(_) => "XML",
153 }
154 }
155}
156
157impl Default for SqlValue {
158 fn default() -> Self {
159 Self::Null
160 }
161}
162
163impl From<bool> for SqlValue {
164 fn from(v: bool) -> Self {
165 Self::Bool(v)
166 }
167}
168
169impl From<i32> for SqlValue {
170 fn from(v: i32) -> Self {
171 Self::Int(v)
172 }
173}
174
175impl From<i64> for SqlValue {
176 fn from(v: i64) -> Self {
177 Self::BigInt(v)
178 }
179}
180
181impl From<f32> for SqlValue {
182 fn from(v: f32) -> Self {
183 Self::Float(v)
184 }
185}
186
187impl From<f64> for SqlValue {
188 fn from(v: f64) -> Self {
189 Self::Double(v)
190 }
191}
192
193impl From<String> for SqlValue {
194 fn from(v: String) -> Self {
195 Self::String(v)
196 }
197}
198
199impl From<&str> for SqlValue {
200 fn from(v: &str) -> Self {
201 Self::String(v.to_owned())
202 }
203}
204
205impl<T> From<Option<T>> for SqlValue
206where
207 T: Into<SqlValue>,
208{
209 fn from(v: Option<T>) -> Self {
210 match v {
211 Some(v) => v.into(),
212 None => Self::Null,
213 }
214 }
215}
216
217#[cfg(feature = "uuid")]
218impl From<uuid::Uuid> for SqlValue {
219 fn from(v: uuid::Uuid) -> Self {
220 Self::Uuid(v)
221 }
222}
223
224#[cfg(feature = "decimal")]
225impl From<rust_decimal::Decimal> for SqlValue {
226 fn from(v: rust_decimal::Decimal) -> Self {
227 Self::Decimal(v)
228 }
229}
230
231#[cfg(feature = "chrono")]
232impl From<chrono::NaiveDate> for SqlValue {
233 fn from(v: chrono::NaiveDate) -> Self {
234 Self::Date(v)
235 }
236}
237
238#[cfg(feature = "chrono")]
239impl From<chrono::NaiveDateTime> for SqlValue {
240 fn from(v: chrono::NaiveDateTime) -> Self {
241 Self::DateTime(v)
242 }
243}
244
245#[cfg(feature = "json")]
246impl From<serde_json::Value> for SqlValue {
247 fn from(v: serde_json::Value) -> Self {
248 Self::Json(v)
249 }
250}