|
32 | 32 | //! ``` |
33 | 33 | //! |
34 | 34 |
|
35 | | -use crate::error::{ClientResult, Error, ParseError}; |
| 35 | +use { |
| 36 | + crate::error::{ClientResult, Error, ParseError}, |
| 37 | + std::ops::Deref, |
| 38 | +}; |
36 | 39 |
|
37 | 40 | /// The value directly returned by the server without any additional type parsing and/or casting |
38 | 41 | #[derive(Debug, PartialEq, Clone)] |
@@ -92,6 +95,13 @@ pub struct Row { |
92 | 95 | values: Vec<Value>, |
93 | 96 | } |
94 | 97 |
|
| 98 | +impl Deref for Row { |
| 99 | + type Target = [Value]; |
| 100 | + fn deref(&self) -> &Self::Target { |
| 101 | + &self.values |
| 102 | + } |
| 103 | +} |
| 104 | + |
95 | 105 | impl Row { |
96 | 106 | pub(crate) fn new(values: Vec<Value>) -> Self { |
97 | 107 | Self { values } |
@@ -267,6 +277,15 @@ macro_rules! from_response_row { |
267 | 277 | Ok(($($elem::from_value(values.next().unwrap())?),*,)) |
268 | 278 | } |
269 | 279 | } |
| 280 | + impl<$($elem: FromValue),*> FromRow for ($($elem),*,) { |
| 281 | + fn from_row(row: Row) -> ClientResult<Self> { |
| 282 | + if row.values().len() != $size { |
| 283 | + return Err(Error::ParseError(ParseError::TypeMismatch)); |
| 284 | + } |
| 285 | + let mut values = row.into_values().into_iter(); |
| 286 | + Ok(($($elem::from_value(values.next().unwrap())?),*,)) |
| 287 | + } |
| 288 | + } |
270 | 289 | )* |
271 | 290 | } |
272 | 291 | } |
@@ -323,3 +342,48 @@ impl FromResponse for Vec<Row> { |
323 | 342 | } |
324 | 343 | } |
325 | 344 | } |
| 345 | + |
| 346 | +/// Trait for parsing a row into a custom type |
| 347 | +pub trait FromRow: Sized { |
| 348 | + /// Parse a row into a custom type |
| 349 | + fn from_row(row: Row) -> ClientResult<Self>; |
| 350 | +} |
| 351 | + |
| 352 | +impl FromRow for Row { |
| 353 | + fn from_row(row: Row) -> ClientResult<Self> { |
| 354 | + Ok(row) |
| 355 | + } |
| 356 | +} |
| 357 | + |
| 358 | +#[derive(Debug, PartialEq)] |
| 359 | +/// A collection of rows |
| 360 | +pub struct Rows<T: FromRow = Row>(Vec<T>); |
| 361 | + |
| 362 | +impl<T: FromRow> Rows<T> { |
| 363 | + /// Consume the [`Rows`] object and get all the rows as a vector |
| 364 | + pub fn into_rows(self) -> Vec<T> { |
| 365 | + self.0 |
| 366 | + } |
| 367 | +} |
| 368 | + |
| 369 | +impl<T: FromRow> FromResponse for Rows<T> { |
| 370 | + fn from_response(resp: Response) -> ClientResult<Self> { |
| 371 | + match resp { |
| 372 | + Response::Rows(rows) => { |
| 373 | + let mut ret = vec![]; |
| 374 | + for row in rows { |
| 375 | + ret.push(T::from_row(row)?); |
| 376 | + } |
| 377 | + Ok(Self(ret)) |
| 378 | + } |
| 379 | + _ => Err(Error::ParseError(ParseError::ResponseMismatch)), |
| 380 | + } |
| 381 | + } |
| 382 | +} |
| 383 | + |
| 384 | +impl<T: FromRow> Deref for Rows<T> { |
| 385 | + type Target = [T]; |
| 386 | + fn deref(&self) -> &Self::Target { |
| 387 | + &self.0 |
| 388 | + } |
| 389 | +} |
0 commit comments