1#[allow(missing_debug_implementations)]
10#[derive(Debug, Hash, PartialEq, Eq, Clone, Copy, serde::Deserialize, serde::Serialize)]
11pub enum SqliteType {
12 Null,
13 Integer,
14 Real,
15 Text,
16 Blob,
17}
18
19#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
20pub enum SqliteRawValue {
21 Null,
22 Integer(i64),
23 Real(f64),
24 Text(String),
25 Blob(Vec<u8>),
26}
27
28impl SqliteRawValue {
29 pub fn kind(&self) -> SqliteType {
30 match self {
31 SqliteRawValue::Null => SqliteType::Null,
32 SqliteRawValue::Integer(_) => SqliteType::Integer,
33 SqliteRawValue::Real(_) => SqliteType::Real,
34 SqliteRawValue::Text(_) => SqliteType::Text,
35 SqliteRawValue::Blob(_) => SqliteType::Blob,
36 }
37 }
38
39 pub fn as_str(&self) -> Option<&str> {
40 match self {
41 SqliteRawValue::Text(s) => Some(s),
42 _ => None,
43 }
44 }
45}
46
47impl From<i32> for SqliteRawValue {
48 fn from(i: i32) -> Self {
49 SqliteRawValue::Integer(i as i64)
50 }
51}
52
53impl From<i64> for SqliteRawValue {
54 fn from(i: i64) -> Self {
55 SqliteRawValue::Integer(i)
56 }
57}
58
59impl TryFrom<&SqliteRawValue> for i64 {
60 type Error = String;
61 fn try_from(v: &SqliteRawValue) -> Result<Self, Self::Error> {
62 match v {
63 SqliteRawValue::Integer(i) => Ok(*i),
64 _ => Err("not an integer".to_string()),
65 }
66 }
67}
68
69impl From<f64> for SqliteRawValue {
70 fn from(f: f64) -> Self {
71 SqliteRawValue::Real(f)
72 }
73}
74
75impl<T> From<Option<T>> for SqliteRawValue
76where
77 T: Into<SqliteRawValue>,
78{
79 fn from(o: Option<T>) -> Self {
80 match o {
81 Some(v) => v.into(),
82 None => SqliteRawValue::Null,
83 }
84 }
85}
86
87impl<'a> From<&'a str> for SqliteRawValue {
88 fn from(s: &'a str) -> Self {
89 SqliteRawValue::Text(s.to_string())
90 }
91}
92
93impl<'a> TryFrom<&'a SqliteRawValue> for &'a str {
94 type Error = String;
95 fn try_from(v: &'a SqliteRawValue) -> Result<Self, Self::Error> {
96 match v {
97 SqliteRawValue::Text(s) => Ok(s),
98 _ => Err("unknown value".to_string()),
99 }
100 }
101}
102
103impl From<String> for SqliteRawValue {
104 fn from(s: String) -> Self {
105 SqliteRawValue::Text(s)
106 }
107}
108
109impl TryFrom<&SqliteRawValue> for String {
110 type Error = String;
111
112 fn try_from(v: &SqliteRawValue) -> Result<Self, Self::Error> {
113 match v {
114 SqliteRawValue::Text(s) => Ok(s.clone()),
115 _ => Err("unknown value".to_string()),
116 }
117 }
118}
119
120impl From<Vec<u8>> for SqliteRawValue {
121 fn from(b: Vec<u8>) -> Self {
122 SqliteRawValue::Blob(b)
123 }
124}
125
126impl TryFrom<&SqliteRawValue> for Vec<u8> {
127 type Error = String;
128
129 fn try_from(v: &SqliteRawValue) -> Result<Self, Self::Error> {
130 match v {
131 SqliteRawValue::Blob(b) => Ok(b.clone()),
132 SqliteRawValue::Text(b) => Ok(b.to_string().into_bytes()),
133 _ => Err(format!("not a blob or string, found: {v:?}")),
134 }
135 }
136}
137
138impl<'a> From<&'a [u8]> for SqliteRawValue {
139 fn from(b: &'a [u8]) -> Self {
140 SqliteRawValue::Blob(b.to_vec())
141 }
142}
143
144impl From<&chrono::DateTime<chrono::Utc>> for SqliteRawValue {
145 fn from(d: &chrono::DateTime<chrono::Utc>) -> Self {
146 SqliteRawValue::Integer(d.timestamp_nanos_opt().unwrap())
147 }
148}
149
150impl From<&mut chrono::DateTime<chrono::Utc>> for SqliteRawValue {
151 fn from(d: &mut chrono::DateTime<chrono::Utc>) -> Self {
152 SqliteRawValue::Integer(d.timestamp_nanos_opt().unwrap())
153 }
154}
155
156impl From<chrono::DateTime<chrono::Utc>> for SqliteRawValue {
157 fn from(d: chrono::DateTime<chrono::Utc>) -> Self {
158 SqliteRawValue::Integer(d.timestamp_nanos_opt().unwrap())
159 }
160}
161
162impl<'a> TryFrom<&'a SqliteRawValue> for chrono::DateTime<chrono::Utc> {
163 type Error = String;
164 fn try_from(v: &'a SqliteRawValue) -> Result<Self, Self::Error> {
165 match v {
166 SqliteRawValue::Integer(i) => Ok(chrono::DateTime::from_timestamp_nanos(*i)),
167 _ => Err("unknown value".to_string()),
168 }
169 }
170}
171
172impl<'a> TryFrom<&'a SqliteRawValue> for bool {
173 type Error = String;
174 fn try_from(v: &'a SqliteRawValue) -> Result<Self, Self::Error> {
175 match v {
176 SqliteRawValue::Integer(0) => Ok(false),
177 SqliteRawValue::Integer(1) => Ok(true),
178 _ => Err("unknown value".to_string()),
179 }
180 }
181}
182
183#[cfg(feature = "rusqlite")]
184impl rusqlite::ToSql for SqliteRawValue {
185 fn to_sql(&self) -> rusqlite::Result<rusqlite::types::ToSqlOutput> {
186 match self {
187 SqliteRawValue::Null => Ok(rusqlite::types::ToSqlOutput::Owned(
188 rusqlite::types::Value::Null,
189 )),
190 SqliteRawValue::Integer(i) => Ok(rusqlite::types::ToSqlOutput::Owned(
191 rusqlite::types::Value::Integer(*i),
192 )),
193 SqliteRawValue::Real(f) => Ok(rusqlite::types::ToSqlOutput::Owned(
194 rusqlite::types::Value::Real(*f),
195 )),
196 SqliteRawValue::Text(s) => Ok(rusqlite::types::ToSqlOutput::Owned(
197 rusqlite::types::Value::Text(s.clone()),
198 )),
199 SqliteRawValue::Blob(b) => Ok(rusqlite::types::ToSqlOutput::Owned(
200 rusqlite::types::Value::Blob(b.clone()),
201 )),
202 }
203 }
204}