1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
//! Support for deserializing database resultsets, and/or individual database rows,
//! and/or individual database values, into rust types.
//!
//! # Result sets
//!
//! Rather than iterating over rows and columns of a resultset, applications
//! can convert resultsets directly into their data structure of choice.
//!
//! This approach allows, in contrast to many ORM mapping variants, using the
//! full flexibility of SQL (projection lists, all kinds of joins, unions, etc, etc).
//! Whatever query an application needs, they just use it, and whatever result structure they need,
//! they just use a corresponding rust structure or tuple into which they deserialize the data
//! in a single method call.
//!
//! The target types for deserialization only need to implement
//! [`serde::de::Deserialize`](https://docs.serde.rs/serde/de/trait.Deserialize.html),
//! which is automatically given for all elementary rust types and tuples,
//! and easily achieved for custom structs using `#[derive(Deserialize)]`.
//!
//! Result sets can _always_ be deserialized into a `Vec<line_struct>`, where
//! `line_struct` matches the field list of the resultset and
//! implements `serde::de::Deserialize`.
//!
//! Similarly, a `Vec<(...)>`, works as well, as long as the tuple
//! members match the field list of the resultset.
//!
//! In addition, `serde_db` also supports structural simplification:
//! depending on the dimension of the resultset, simplified target types can be
//! chosen for deserialization:
//!
//! * If the resultset contains only a single line (e.g. because you specified
//!   TOP 1 in your select),
//!   then you can optionally choose to deserialize directly into a plain `line_struct`.
//!
//! * If the resultset contains only a single column, then you can optionally choose to
//!   deserialize into a `Vec<plain_field>`.
//!
//! * If the resultset contains only a single value (one row with one column),
//!   then you can optionally choose to deserialize into a plain `line_struct`,
//!   or a `Vec<plain_field>`, or a plain variable.
//!
//! The below examples assume the DB driver exposes on its
//! resultset type a function
//! `fn into_typed<'de, T: serde::de::Deserialize<'de>>(self) -> mock_db::Result<T>`,
//! which is implemented using `serde_db`.
//!
//! ## Convert a n×m resultset into a Vec of structs:
//!
//! ```rust,ignore
//! #[derive(serde_derive::Deserialize)]
//! struct MyStruct {
//!   // ...
//! }
//!
//! // let resultset = ...;
//! let data: Vec<MyStruct> = resultset.into_typed()?;
//! ```
//!
//! Note that `MyStruct` has to implement `serde::de::Deserialize`.
//!
//! ## Convert a n×1 resultset into a Vec of fields:
//!
//! ```rust,ignore
//! let vec_s: Vec<String> = resultset.into_typed()?;
//! ```
//!
//! ## Convert a 1×1 resultset into a single field:
//!
//! ```rust,ignore
//! let s: String = resultset.into_typed()?;
//! ```
//!
//! # Rows
//!
//! ## Convert rows into tuples or structs
//!
//! For better streaming of large resultsets, you might want to iterate over the rows, like in
//!
//! ```rust,ignore
//! for row in resultset {
//!     let t: (String, NaiveDateTime, i32, Option<i32>) = row.into_typed()?;
//! }
//! ```
//!
//! or
//!
//! ```rust,ignore
//! for row in resultset {
//!     let data: MyStruct = row.into_typed()?;
//! }
//! ```
//!
//! # Individual values
//!
//! When necessary, you can also convert individual values directly into an adequate rust type:
//!
//! ```rust,ignore
//! for row in resultset {
//!     let date: NaiveDateTime = row.field_into_typed(2)?;
//!     ...
//! }
//! ```
//!
//! # Note for implementors
//!
//! Implementing DB drivers need
//! to implement [`DeserializableResultset`](trait.DeserializableResultset.html) and
//! [`DeserializableRow`](trait.DeserializableRow.html), which are trivial,
//! and [`DbValue`](trait.DbValue.html), which is a bit more effort
//! (an example can be found in the tests of this crate), depending on the flexibility
//! you want to offer.
//!
//! We further recommend adding a method like `into_typed()` directly on the
//! driver's class for resultsets with a plain delegation to the _provided_ method
//! [`DeserializableResultset::into_typed()`](trait.DeserializableResultset.html#method.into_typed).
//! The same should be done for rows.
//!
//! By this, the deserialization functionality of `serde_db` can be provided
//! to the users of the DB driver without forcing them to import `serde_db`.

mod conversion_error;
mod db_value;
mod db_value_into;
mod deserializable_resultset;
mod deserializable_row;
mod deserialization_error;
mod field_deserializer;
mod row_deserializer;
mod rs_deserializer;

pub use self::conversion_error::ConversionError;
pub use self::db_value::DbValue;
pub use self::db_value_into::DbValueInto;
pub use self::deserializable_resultset::DeserializableResultset;
pub use self::deserializable_row::DeserializableRow;
pub use self::deserialization_error::{DeserializationError, DeserializationResult};