Skip to content

Commit

Permalink
Fix nightly rustc warnings in generated impls (#242)
Browse files Browse the repository at this point in the history
  • Loading branch information
jayvdb authored Apr 16, 2024
1 parent 0a7824d commit d7cfee4
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 46 deletions.
4 changes: 2 additions & 2 deletions butane/tests/common/blog.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use butane::prelude::*;
use butane::{dataresult, model};
//! Helpers for several tests.
use butane::{dataresult, model, DataObject};
use butane::{db::Connection, ForeignKey, Many};
#[cfg(feature = "datetime")]
use chrono::{naive::NaiveDateTime, offset::Utc};
Expand Down
89 changes: 52 additions & 37 deletions butane_core/src/codegen/dbobj.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,34 @@ pub fn impl_dbobject(ast_struct: &ItemStruct, config: &Config) -> TokenStream2 {
})
.collect();

let conn_arg_name = if many_save.is_empty() {
syn::Ident::new("_conn", Span::call_site())
} else {
syn::Ident::new("conn", Span::call_site())
};

let non_auto_values_fn = if values.is_empty() {
quote!(
fn non_auto_values(&self, _include_pk: bool) -> Vec<butane::SqlValRef> {
return vec![];
}
)
} else {
quote!(
fn non_auto_values(&self, include_pk: bool) -> Vec<butane::SqlValRef> {
let mut values: Vec<butane::SqlValRef> = Vec::with_capacity(
<Self as butane::DataResult>::COLUMNS.len()
);
if include_pk {
#(#values)*
} else {
#(#values_no_pk)*
}
values
}
)
};

let dataresult = impl_dataresult(ast_struct, tyname, config);
// Note the many impls following DataObject can not be generic because they implement for T and &T,
// which become conflicting types as &T is included in T.
Expand All @@ -71,21 +99,11 @@ pub fn impl_dbobject(ast_struct: &ItemStruct, config: &Config) -> TokenStream2 {
fn pk_mut(&mut self) -> &mut impl butane::PrimaryKeyType {
&mut self.#pkident
}
fn save_many_to_many(&mut self, conn: &impl butane::db::ConnectionMethods) -> butane::Result<()> {
fn save_many_to_many(&mut self, #conn_arg_name: &impl butane::db::ConnectionMethods) -> butane::Result<()> {
#many_save
Ok(())
}
fn values(&self, include_pk: bool) -> Vec<butane::SqlValRef> {
let mut values: Vec<butane::SqlValRef> = Vec::with_capacity(
<Self as butane::DataResult>::COLUMNS.len()
);
if (include_pk) {
#(#values)*
} else {
#(#values_no_pk)*
}
values
}
#non_auto_values_fn
}

impl butane::DataObject for #tyname {
Expand All @@ -101,20 +119,24 @@ pub fn impl_dbobject(ast_struct: &ItemStruct, config: &Config) -> TokenStream2 {
}
impl butane::ToSql for #tyname {
fn to_sql(&self) -> butane::SqlVal {
#[allow(unused_imports)]
use butane::DataObject;
butane::ToSql::to_sql(self.pk())
}
fn to_sql_ref(&self) -> butane::SqlValRef<'_> {
#[allow(unused_imports)]
use butane::DataObject;
butane::ToSql::to_sql_ref(self.pk())
}
}
impl butane::ToSql for &#tyname {
fn to_sql(&self) -> butane::SqlVal {
#[allow(unused_imports)]
use butane::DataObject;
butane::ToSql::to_sql(self.pk())
}
fn to_sql_ref(&self) -> butane::SqlValRef<'_> {
#[allow(unused_imports)]
use butane::DataObject;
butane::ToSql::to_sql_ref(self.pk())
}
Expand All @@ -131,12 +153,14 @@ pub fn impl_dbobject(ast_struct: &ItemStruct, config: &Config) -> TokenStream2 {
}
impl butane::AsPrimaryKey<#tyname> for #tyname {
fn as_pk(&self) -> std::borrow::Cow<<Self as butane::DataObject>::PKType> {
#[allow(unused_imports)]
use butane::DataObject;
std::borrow::Cow::Borrowed(self.pk())
}
}
impl butane::AsPrimaryKey<#tyname> for &#tyname {
fn as_pk(&self) -> std::borrow::Cow<<#tyname as butane::DataObject>::PKType> {
#[allow(unused_imports)]
use butane::DataObject;
std::borrow::Cow::Borrowed(self.pk())
}
Expand Down Expand Up @@ -168,18 +192,19 @@ pub fn impl_dataresult(ast_struct: &ItemStruct, dbo: &Ident, config: &Config) ->
})
.collect();

let dbo_is_self = dbo == tyname;
let ctor = if dbo_is_self {
let from_row_body = if many_init.is_empty() {
quote!(
let mut obj = #tyname {
#(#rows),*
};
Ok(#tyname {
#(#rows),*
})
)
} else {
quote!(
let mut obj = #tyname {
#(#rows),*
};
#many_init
Ok(obj)
)
};

Expand All @@ -189,18 +214,17 @@ pub fn impl_dataresult(ast_struct: &ItemStruct, dbo: &Ident, config: &Config) ->
const COLUMNS: &'static [butane::db::Column] = &[
#cols
];
fn from_row(mut row: &dyn butane::db::BackendRow) -> butane::Result<Self> {
fn from_row(row: &dyn butane::db::BackendRow) -> butane::Result<Self> {
if row.len() != #numdbfields {
return Err(butane::Error::BoundsError(
"Found unexpected number of columns in row for DataResult".to_string()
));
}
#ctor
#many_init
Ok(obj)
#from_row_body
}
fn query() -> butane::query::Query<Self> {
use butane::prelude::DataObject;
#[allow(unused_imports)]
use butane::DataObject;
butane::query::Query::new(Self::DBO::TABLE)
}
}
Expand Down Expand Up @@ -322,8 +346,9 @@ fn rows_for_from(ast_struct: &ItemStruct) -> Vec<TokenStream2> {
if is_row_field(f) {
let fty = &f.ty;
let ret = quote!(
#ident: butane::FromSql::from_sql_ref(
row.get(#i, <#fty as butane::FieldType>::SQLTYPE)?)?
#ident: butane::FromSql::from_sql_ref(
row.get(#i, <#fty as butane::FieldType>::SQLTYPE)?
)?
);
i += 1;
ret
Expand Down Expand Up @@ -398,26 +423,16 @@ fn verify_fields(ast_struct: &ItemStruct) -> Option<TokenStream2> {
}

/// Builds code for pushing SqlVals for each column satisfying predicate into a vec called `values`
/// that excludes any auto values.
fn push_values<P>(ast_struct: &ItemStruct, mut predicate: P) -> Vec<TokenStream2>
where
P: FnMut(&Field) -> bool,
{
fields(ast_struct)
.filter(|f| is_row_field(f) && predicate(f))
.filter(|f| is_row_field(f) && !is_auto(f) && predicate(f))
.map(|f| {
let ident = f.ident.clone().unwrap();
if is_row_field(f) {
if !is_auto(f) {
quote!(values.push(butane::ToSql::to_sql_ref(&self.#ident));)
} else {
quote!()
}
} else if is_many_to_many(f) {
// No-op
quote!()
} else {
make_compile_error!(f.span()=> "Unexpected struct field")
}
quote!(values.push(butane::ToSql::to_sql_ref(&self.#ident));)
})
.collect()
}
17 changes: 11 additions & 6 deletions butane_core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,9 @@ pub mod internal {
/// Performed automatically by `save`. You do not need to call this directly.
fn save_many_to_many(&mut self, conn: &impl ConnectionMethods) -> Result<()>;

/// Returns the Sql values of all columns. Used internally. You are
/// unlikely to need to call this directly.
fn values(&self, include_pk: bool) -> Vec<SqlValRef>;
/// Returns the Sql values of all columns except not any auto columns.
/// Used internally. You are unlikely to need to call this directly.
fn non_auto_values(&self, include_pk: bool) -> Vec<SqlValRef>;
}
}

Expand Down Expand Up @@ -148,21 +148,26 @@ pub trait DataObject: DataResult<DBO = Self> + internal::DataObjectInternal {
pkcol,
self.pk().to_sql_ref(),
Self::NON_AUTO_COLUMNS,
&self.values(false),
&self.non_auto_values(false),
)?;
} else {
// invalid pk, do an insert
let pk = conn.insert_returning_pk(
Self::TABLE,
Self::NON_AUTO_COLUMNS,
&pkcol,
&self.values(true),
&self.non_auto_values(true),
)?;
self.pk_mut().initialize(pk)?;
};
} else {
// No AutoPk to worry about, do an upsert
conn.insert_or_replace(Self::TABLE, Self::COLUMNS, &pkcol, &self.values(true))?;
conn.insert_or_replace(
Self::TABLE,
Self::COLUMNS,
&pkcol,
&self.non_auto_values(true),
)?;
}

self.save_many_to_many(conn)?;
Expand Down
2 changes: 1 addition & 1 deletion butane_core/src/migrations/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,7 @@ impl crate::internal::DataObjectInternal for ButaneMigration {
fn pk_mut(&mut self) -> &mut impl PrimaryKeyType {
&mut self.name
}
fn values(&self, include_pk: bool) -> Vec<SqlValRef> {
fn non_auto_values(&self, include_pk: bool) -> Vec<SqlValRef> {
let mut values: Vec<SqlValRef<'_>> = Vec::with_capacity(2usize);
if include_pk {
values.push(self.name.to_sql_ref());
Expand Down

0 comments on commit d7cfee4

Please sign in to comment.