1use crate::error::DactylError;
4use serde::{Deserialize, Serialize};
5
6#[derive(Debug, Clone, Default, Serialize, Deserialize)]
8pub struct Rows(pub Vec<Row>);
9
10impl Rows {
11 pub fn as_slice(&self) -> &[Row] {
13 &self.0
14 }
15
16 pub fn iter(&self) -> std::slice::Iter<'_, Row> {
18 self.0.iter()
19 }
20
21 pub fn len(&self) -> usize {
23 self.0.len()
24 }
25
26 pub fn is_empty(&self) -> bool {
28 self.0.is_empty()
29 }
30}
31
32impl IntoIterator for Rows {
33 type Item = Row;
34 type IntoIter = std::vec::IntoIter<Row>;
35
36 fn into_iter(self) -> Self::IntoIter {
37 self.0.into_iter()
38 }
39}
40
41#[derive(Debug, Clone, Serialize, Deserialize)]
44pub struct Row {
45 pub columns: Vec<String>,
47 pub values: Vec<serde_json::Value>,
49}
50
51#[derive(Debug, Clone, PartialEq)]
53pub enum Parameter {
54 Null,
55 Bool(bool),
56 Integer(i64),
57 Real(f64),
58 Text(String),
59}
60
61impl serde::Serialize for Parameter {
62 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
63 where
64 S: serde::Serializer,
65 {
66 match self {
67 Parameter::Null => serializer.serialize_unit(),
68 Parameter::Bool(b) => serializer.serialize_bool(*b),
69 Parameter::Integer(i) => serializer.serialize_i64(*i),
70 Parameter::Real(f) => serializer.serialize_f64(*f),
71 Parameter::Text(s) => serializer.serialize_str(s),
72 }
73 }
74}
75
76impl<'de> serde::Deserialize<'de> for Parameter {
77 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
78 where
79 D: serde::Deserializer<'de>,
80 {
81 struct ParameterVisitor;
82 impl<'de> serde::de::Visitor<'de> for ParameterVisitor {
83 type Value = Parameter;
84 fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
85 formatter.write_str("a database parameter value")
86 }
87 fn visit_none<E>(self) -> Result<Self::Value, E>
88 where
89 E: serde::de::Error,
90 {
91 Ok(Parameter::Null)
92 }
93 fn visit_unit<E>(self) -> Result<Self::Value, E>
94 where
95 E: serde::de::Error,
96 {
97 Ok(Parameter::Null)
98 }
99 fn visit_bool<E>(self, v: bool) -> Result<Self::Value, E>
100 where
101 E: serde::de::Error,
102 {
103 Ok(Parameter::Bool(v))
104 }
105 fn visit_i64<E>(self, v: i64) -> Result<Self::Value, E>
106 where
107 E: serde::de::Error,
108 {
109 Ok(Parameter::Integer(v))
110 }
111 fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>
112 where
113 E: serde::de::Error,
114 {
115 Ok(Parameter::Integer(v as i64))
116 }
117 fn visit_f64<E>(self, v: f64) -> Result<Self::Value, E>
118 where
119 E: serde::de::Error,
120 {
121 Ok(Parameter::Real(v))
122 }
123 fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
124 where
125 E: serde::de::Error,
126 {
127 Ok(Parameter::Text(v.to_string()))
128 }
129 fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
130 where
131 E: serde::de::Error,
132 {
133 Ok(Parameter::Text(v))
134 }
135 }
136 deserializer.deserialize_any(ParameterVisitor)
137 }
138}
139
140impl From<i64> for Parameter {
141 fn from(v: i64) -> Self {
142 Parameter::Integer(v)
143 }
144}
145impl From<i32> for Parameter {
146 fn from(v: i32) -> Self {
147 Parameter::Integer(v as i64)
148 }
149}
150impl From<u32> for Parameter {
151 fn from(v: u32) -> Self {
152 Parameter::Integer(v as i64)
153 }
154}
155impl From<usize> for Parameter {
156 fn from(v: usize) -> Self {
157 Parameter::Integer(v as i64)
158 }
159}
160impl From<bool> for Parameter {
161 fn from(v: bool) -> Self {
162 Parameter::Bool(v)
163 }
164}
165impl From<f64> for Parameter {
166 fn from(v: f64) -> Self {
167 Parameter::Real(v)
168 }
169}
170impl From<String> for Parameter {
171 fn from(v: String) -> Self {
172 Parameter::Text(v)
173 }
174}
175impl From<&str> for Parameter {
176 fn from(v: &str) -> Self {
177 Parameter::Text(v.to_string())
178 }
179}
180
181impl From<Option<String>> for Parameter {
182 fn from(v: Option<String>) -> Self {
183 match v {
184 Some(s) => Parameter::Text(s),
185 None => Parameter::Null,
186 }
187 }
188}
189
190impl From<Option<&str>> for Parameter {
191 fn from(v: Option<&str>) -> Self {
192 match v {
193 Some(s) => Parameter::Text(s.to_string()),
194 None => Parameter::Null,
195 }
196 }
197}
198
199impl From<Option<i64>> for Parameter {
200 fn from(v: Option<i64>) -> Self {
201 match v {
202 Some(i) => Parameter::Integer(i),
203 None => Parameter::Null,
204 }
205 }
206}
207
208impl From<Option<bool>> for Parameter {
209 fn from(v: Option<bool>) -> Self {
210 match v {
211 Some(b) => Parameter::Bool(b),
212 None => Parameter::Null,
213 }
214 }
215}
216
217pub trait RowIndex: std::fmt::Debug {
219 fn idx(&self, row: &Row) -> Option<usize>;
221}
222
223impl RowIndex for usize {
224 fn idx(&self, _row: &Row) -> Option<usize> {
225 Some(*self)
226 }
227}
228
229impl RowIndex for &str {
230 fn idx(&self, row: &Row) -> Option<usize> {
231 row.columns.iter().position(|c| c == self)
232 }
233}
234
235impl RowIndex for String {
236 fn idx(&self, row: &Row) -> Option<usize> {
237 row.columns.iter().position(|c| c == self)
238 }
239}
240
241impl Row {
242 pub fn get<I: RowIndex, T: serde::de::DeserializeOwned>(
250 &self,
251 index: I,
252 ) -> Result<T, DactylError> {
253 let i = self.idx(&index)?;
254 let val = &self.values[i];
255 serde_json::from_value(val.clone()).map_err(|e| {
256 DactylError::Conversion(format!(
257 "failed to convert column {:?} to target type: {}",
258 index, e
259 ))
260 })
261 }
262
263 pub fn get_bool<I: RowIndex>(&self, index: I) -> Result<bool, DactylError> {
265 let i = self.idx(&index)?;
266 match &self.values[i] {
267 serde_json::Value::Bool(b) => Ok(*b),
268 serde_json::Value::Number(n) if n.as_i64() == Some(0) => Ok(false),
269 serde_json::Value::Number(n) if n.as_i64() == Some(1) => Ok(true),
270 other => Err(DactylError::Conversion(format!(
271 "cannot read {other:?} as bool at column {:?}",
272 index
273 ))),
274 }
275 }
276
277 pub fn get_int<I: RowIndex>(&self, index: I) -> Result<i64, DactylError> {
279 let i = self.idx(&index)?;
280 match &self.values[i] {
281 serde_json::Value::Number(n) => n.as_i64().ok_or_else(|| {
282 DactylError::Conversion(format!("value is not i64 at column {:?}", index))
283 }),
284 other => Err(DactylError::Conversion(format!(
285 "cannot read {other:?} as i64 at column {:?}",
286 index
287 ))),
288 }
289 }
290
291 pub fn get_real<I: RowIndex>(&self, index: I) -> Result<f64, DactylError> {
293 let i = self.idx(&index)?;
294 match &self.values[i] {
295 serde_json::Value::Number(n) => n.as_f64().ok_or_else(|| {
296 DactylError::Conversion(format!("value is not f64 at column {:?}", index))
297 }),
298 other => Err(DactylError::Conversion(format!(
299 "cannot read {other:?} as f64 at column {:?}",
300 index
301 ))),
302 }
303 }
304
305 pub fn get_str<I: RowIndex>(&self, index: I) -> Result<String, DactylError> {
307 let i = self.idx(&index)?;
308 match &self.values[i] {
309 serde_json::Value::String(s) => Ok(s.clone()),
310 other => Err(DactylError::Conversion(format!(
311 "cannot read {other:?} as String at column {:?}",
312 index
313 ))),
314 }
315 }
316
317 pub fn get_json<I: RowIndex>(&self, index: I) -> Result<serde_json::Value, DactylError> {
319 let i = self.idx(&index)?;
320 Ok(self.values[i].clone())
321 }
322
323 fn idx<I: RowIndex>(&self, index: &I) -> Result<usize, DactylError> {
324 index
325 .idx(self)
326 .ok_or_else(|| DactylError::ColumnNotFound(format!("{:?}", index)))
327 .and_then(|i| {
328 if i < self.values.len() {
329 Ok(i)
330 } else {
331 Err(DactylError::ColumnNotFound(format!(
332 "index {i} out of bounds"
333 )))
334 }
335 })
336 }
337}