Skip to content

Commit 9635290

Browse files
authored
Merge pull request diesel-rs#2599 from Ten0/faillible_queryable_stillgeneric
Faillible Queryable
2 parents 199f883 + fd9d5a5 commit 9635290

12 files changed

Lines changed: 62 additions & 50 deletions

File tree

CHANGELOG.md

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -136,8 +136,15 @@ for Rust libraries in [RFC #1105](https://github.com/rust-lang/rfcs/blob/master/
136136
Similary, `only_tabels` and `except_tables` in `diesel.toml` are treated as regular expressions.
137137

138138
* Now you can sort column fields by name with the `column-sorting` option.
139-
It can be set to either `ordinal_position` (default) or `name`.
140-
This ensures stable sorting even if columns are removed and re-added.
139+
It can be set to either `ordinal_position` (default) or `name`.
140+
This ensures stable sorting even if columns are removed and re-added.
141+
142+
* The `Queryable<ST,DB>` trait was updated to be made faillible, in order to properly handle
143+
cases where you detect a data inconsistency between fields on deserialization
144+
(that e.g. was supposed to be made impossible by DB `CHECK`s). The `build` function now
145+
returns a
146+
[`diesel::deserialize::Result<Self>`](https://docs.diesel.rs/master/diesel/deserialize/type.Result.html)
147+
instead of a `Self`.
141148

142149
### Fixed
143150

diesel/src/deserialize.rs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ pub type Result<T> = result::Result<T, Box<dyn Error + Send + Sync>>;
5757
/// #
5858
/// # use schema::users;
5959
/// # use diesel::backend::{self, Backend};
60-
/// # use diesel::deserialize::{Queryable, FromSql};
60+
/// # use diesel::deserialize::{self, Queryable, FromSql};
6161
/// # use diesel::sql_types::Text;
6262
/// #
6363
/// struct LowercaseString(String);
@@ -75,8 +75,8 @@ pub type Result<T> = result::Result<T, Box<dyn Error + Send + Sync>>;
7575
/// {
7676
/// type Row = String;
7777
///
78-
/// fn build(s: String) -> Self {
79-
/// LowercaseString(s.to_lowercase())
78+
/// fn build(s: String) -> deserialize::Result<Self> {
79+
/// Ok(LowercaseString(s.to_lowercase()))
8080
/// }
8181
/// }
8282
///
@@ -107,7 +107,7 @@ pub type Result<T> = result::Result<T, Box<dyn Error + Send + Sync>>;
107107
/// # include!("doctest_setup.rs");
108108
/// #
109109
/// use schema::users;
110-
/// use diesel::deserialize::Queryable;
110+
/// use diesel::deserialize::{self, Queryable};
111111
///
112112
/// # /*
113113
/// type DB = diesel::sqlite::Sqlite;
@@ -122,11 +122,11 @@ pub type Result<T> = result::Result<T, Box<dyn Error + Send + Sync>>;
122122
/// impl Queryable<users::SqlType, DB> for User {
123123
/// type Row = (i32, String);
124124
///
125-
/// fn build(row: Self::Row) -> Self {
126-
/// User {
125+
/// fn build(row: Self::Row) -> deserialize::Result<Self> {
126+
/// Ok(User {
127127
/// id: row.0,
128128
/// name: row.1.to_lowercase(),
129-
/// }
129+
/// })
130130
/// }
131131
/// }
132132
///
@@ -143,7 +143,7 @@ pub type Result<T> = result::Result<T, Box<dyn Error + Send + Sync>>;
143143
/// # Ok(())
144144
/// # }
145145
/// ```
146-
pub trait Queryable<ST, DB>
146+
pub trait Queryable<ST, DB>: Sized
147147
where
148148
DB: Backend,
149149
{
@@ -153,7 +153,7 @@ where
153153
type Row: FromStaticSqlRow<ST, DB>;
154154

155155
/// Construct an instance of this type
156-
fn build(row: Self::Row) -> Self;
156+
fn build(row: Self::Row) -> Result<Self>;
157157
}
158158

159159
#[doc(inline)]
@@ -394,7 +394,7 @@ where
394394
{
395395
fn build_from_row<'a>(row: &impl Row<'a, DB>) -> Result<Self> {
396396
let row = <T::Row as FromStaticSqlRow<ST, DB>>::build_from_row(row)?;
397-
Ok(T::build(row))
397+
T::build(row)
398398
}
399399
}
400400

diesel/src/pg/types/ranges.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,8 +99,8 @@ where
9999
{
100100
type Row = Self;
101101

102-
fn build(row: Self) -> Self {
103-
row
102+
fn build(row: Self) -> deserialize::Result<Self> {
103+
Ok(row)
104104
}
105105
}
106106

diesel/src/pg/types/record.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,8 @@ macro_rules! tuple_impls {
7373
{
7474
type Row = Self;
7575

76-
fn build(row: Self::Row) -> Self {
77-
row
76+
fn build(row: Self::Row) -> deserialize::Result<Self> {
77+
Ok(row)
7878
}
7979
}
8080

diesel/src/type_impls/option.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,8 +106,8 @@ where
106106
{
107107
type Row = Self;
108108

109-
fn build(row: Self::Row) -> Self {
110-
row
109+
fn build(row: Self::Row) -> deserialize::Result<Self> {
110+
Ok(row)
111111
}
112112
}
113113

diesel/src/type_impls/primitives.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -241,8 +241,8 @@ where
241241
{
242242
type Row = Self;
243243

244-
fn build(row: Self::Row) -> Self {
245-
row
244+
fn build(row: Self::Row) -> deserialize::Result<Self> {
245+
Ok(row)
246246
}
247247
}
248248

diesel/src/type_impls/tuples.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -235,8 +235,8 @@ macro_rules! tuple_impls {
235235
{
236236
type Row = Self;
237237

238-
fn build(row: Self::Row) -> Self {
239-
row
238+
fn build(row: Self::Row) -> deserialize::Result<Self> {
239+
Ok(row)
240240
}
241241
}
242242

@@ -265,8 +265,8 @@ macro_rules! tuple_impls {
265265
{
266266
type Row = Self;
267267

268-
fn build(row: Self::Row) -> Self {
269-
row
268+
fn build(row: Self::Row) -> deserialize::Result<Self> {
269+
Ok(row)
270270
}
271271
}
272272

diesel_cli/src/infer_schema_internals/data_structures.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#[cfg(feature = "uses_information_schema")]
22
use diesel::backend::Backend;
3-
use diesel::deserialize::{FromStaticSqlRow, Queryable};
3+
use diesel::deserialize::{self, FromStaticSqlRow, Queryable};
44
#[cfg(feature = "sqlite")]
55
use diesel::sqlite::Sqlite;
66

@@ -80,8 +80,8 @@ where
8080
{
8181
type Row = (String, String, String);
8282

83-
fn build(row: Self::Row) -> Self {
84-
ColumnInformation::new(row.0, row.1, row.2 == "YES")
83+
fn build(row: Self::Row) -> deserialize::Result<Self> {
84+
Ok(ColumnInformation::new(row.0, row.1, row.2 == "YES"))
8585
}
8686
}
8787

@@ -92,8 +92,8 @@ where
9292
{
9393
type Row = (i32, String, String, bool, Option<String>, bool);
9494

95-
fn build(row: Self::Row) -> Self {
96-
ColumnInformation::new(row.1, row.2, !row.3)
95+
fn build(row: Self::Row) -> deserialize::Result<Self> {
96+
Ok(ColumnInformation::new(row.1, row.2, !row.3))
9797
}
9898
}
9999

diesel_cli/src/infer_schema_internals/table_data.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use diesel::backend::Backend;
2-
use diesel::deserialize::{FromStaticSqlRow, Queryable};
2+
use diesel::deserialize::{self, FromStaticSqlRow, Queryable};
33
use std::fmt;
44
use std::str::FromStr;
55

@@ -60,8 +60,8 @@ where
6060
{
6161
type Row = (String, String);
6262

63-
fn build((name, schema): Self::Row) -> Self {
64-
TableName::new(name, schema)
63+
fn build((name, schema): Self::Row) -> deserialize::Result<Self> {
64+
Ok(TableName::new(name, schema))
6565
}
6666
}
6767

diesel_derives/src/from_sql_row.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,15 +29,15 @@ pub fn derive(mut item: syn::DeriveInput) -> Result<TokenStream, Diagnostic> {
2929
let (impl_generics, _, where_clause) = item.generics.split_for_impl();
3030

3131
Ok(wrap_in_dummy_mod(quote! {
32-
use diesel::deserialize::{FromSql, Queryable};
32+
use diesel::deserialize::{self, FromSql, Queryable};
3333

3434
impl #impl_generics Queryable<__ST, __DB> for #struct_ty
3535
#where_clause
3636
{
3737
type Row = Self;
3838

39-
fn build(row: Self::Row) -> Self {
40-
row
39+
fn build(row: Self::Row) -> deserialize::Result<Self> {
40+
Ok(row)
4141
}
4242
}
4343
}))

0 commit comments

Comments
 (0)