1use std::borrow::Cow;
4
5#[derive(Debug, Clone, PartialEq)]
7pub enum SqlValue {
8 Null,
9 Bool(bool),
10 I64(i64),
11 U64(u64),
12 F64(f64),
13 String(Cow<'static, str>),
14 Bytes(Vec<u8>),
15 DateTime(SqlDateTime),
16}
17
18#[derive(Debug, Clone, PartialEq)]
20pub struct SqlDateTime {
21 pub dt: time::OffsetDateTime,
22 pub tz_abbr: Option<Cow<'static, str>>,
23}
24
25impl SqlDateTime {
26 pub fn new(dt: time::OffsetDateTime) -> Self {
27 Self { dt, tz_abbr: None }
28 }
29
30 pub fn with_tz_abbr(mut self, abbr: impl Into<Cow<'static, str>>) -> Self {
31 self.tz_abbr = Some(abbr.into());
32 self
33 }
34}
35
36impl SqlValue {
37 pub fn from_option<T: Into<SqlValue>>(v: Option<T>) -> Self {
39 match v {
40 Some(v) => v.into(),
41 None => Self::Null,
42 }
43 }
44}
45
46impl From<()> for SqlValue {
47 fn from(_: ()) -> Self {
48 Self::Null
49 }
50}
51
52impl From<bool> for SqlValue {
53 fn from(v: bool) -> Self {
54 Self::Bool(v)
55 }
56}
57
58impl From<i8> for SqlValue {
59 fn from(v: i8) -> Self {
60 Self::I64(v as i64)
61 }
62}
63
64impl From<i16> for SqlValue {
65 fn from(v: i16) -> Self {
66 Self::I64(v as i64)
67 }
68}
69
70impl From<i32> for SqlValue {
71 fn from(v: i32) -> Self {
72 Self::I64(v as i64)
73 }
74}
75
76impl From<i64> for SqlValue {
77 fn from(v: i64) -> Self {
78 Self::I64(v)
79 }
80}
81
82impl From<u8> for SqlValue {
83 fn from(v: u8) -> Self {
84 Self::U64(v as u64)
85 }
86}
87
88impl From<u16> for SqlValue {
89 fn from(v: u16) -> Self {
90 Self::U64(v as u64)
91 }
92}
93
94impl From<u32> for SqlValue {
95 fn from(v: u32) -> Self {
96 Self::U64(v as u64)
97 }
98}
99
100impl From<u64> for SqlValue {
101 fn from(v: u64) -> Self {
102 Self::U64(v)
103 }
104}
105
106impl From<f32> for SqlValue {
107 fn from(v: f32) -> Self {
108 Self::F64(v as f64)
109 }
110}
111
112impl From<f64> for SqlValue {
113 fn from(v: f64) -> Self {
114 Self::F64(v)
115 }
116}
117
118impl From<String> for SqlValue {
119 fn from(v: String) -> Self {
120 Self::String(Cow::Owned(v))
121 }
122}
123
124impl From<&'static str> for SqlValue {
125 fn from(v: &'static str) -> Self {
126 Self::String(Cow::Borrowed(v))
127 }
128}
129
130impl From<Vec<u8>> for SqlValue {
131 fn from(v: Vec<u8>) -> Self {
132 Self::Bytes(v)
133 }
134}
135
136impl From<time::OffsetDateTime> for SqlValue {
137 fn from(v: time::OffsetDateTime) -> Self {
138 Self::DateTime(SqlDateTime::new(v))
139 }
140}
141
142#[cfg(test)]
143mod tests {
144 use super::SqlValue;
145
146 #[test]
147 fn from_option_some() {
148 assert_eq!(SqlValue::from_option(Some(123_i64)), SqlValue::I64(123));
149 }
150
151 #[test]
152 fn from_option_none() {
153 assert_eq!(SqlValue::from_option::<i64>(None), SqlValue::Null);
154 }
155
156 #[test]
157 fn from_unit_is_null() {
158 let v: SqlValue = ().into();
159 assert_eq!(v, SqlValue::Null);
160 }
161
162 #[test]
163 fn from_string_borrowed() {
164 let v: SqlValue = "abc".into();
165 assert_eq!(v, SqlValue::String("abc".into()));
166 }
167
168 #[test]
169 fn from_string_owned() {
170 let v: SqlValue = String::from("abc").into();
171 assert_eq!(v, SqlValue::String("abc".into()));
172 }
173}