From d7cfee49e2b74d82034496aeb7c2ffc4bb544fc7 Mon Sep 17 00:00:00 2001 From: John Vandenberg Date: Tue, 16 Apr 2024 09:37:39 +0800 Subject: [PATCH] Fix nightly rustc warnings in generated impls (#242) --- butane/tests/common/blog.rs | 4 +- butane_core/src/codegen/dbobj.rs | 89 ++++++++++++++++++------------- butane_core/src/lib.rs | 17 +++--- butane_core/src/migrations/mod.rs | 2 +- 4 files changed, 66 insertions(+), 46 deletions(-) diff --git a/butane/tests/common/blog.rs b/butane/tests/common/blog.rs index ff64503c..d2cc9847 100644 --- a/butane/tests/common/blog.rs +++ b/butane/tests/common/blog.rs @@ -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}; diff --git a/butane_core/src/codegen/dbobj.rs b/butane_core/src/codegen/dbobj.rs index bf5c0164..19c9c6b4 100644 --- a/butane_core/src/codegen/dbobj.rs +++ b/butane_core/src/codegen/dbobj.rs @@ -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 { + return vec![]; + } + ) + } else { + quote!( + fn non_auto_values(&self, include_pk: bool) -> Vec { + let mut values: Vec = Vec::with_capacity( + ::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. @@ -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 { - let mut values: Vec = Vec::with_capacity( - ::COLUMNS.len() - ); - if (include_pk) { - #(#values)* - } else { - #(#values_no_pk)* - } - values - } + #non_auto_values_fn } impl butane::DataObject for #tyname { @@ -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()) } @@ -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<::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()) } @@ -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) ) }; @@ -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 { + fn from_row(row: &dyn butane::db::BackendRow) -> butane::Result { 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 { - use butane::prelude::DataObject; + #[allow(unused_imports)] + use butane::DataObject; butane::query::Query::new(Self::DBO::TABLE) } } @@ -322,8 +346,9 @@ fn rows_for_from(ast_struct: &ItemStruct) -> Vec { 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 @@ -398,26 +423,16 @@ fn verify_fields(ast_struct: &ItemStruct) -> Option { } /// Builds code for pushing SqlVals for each column satisfying predicate into a vec called `values` +/// that excludes any auto values. fn push_values

(ast_struct: &ItemStruct, mut predicate: P) -> Vec 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() } diff --git a/butane_core/src/lib.rs b/butane_core/src/lib.rs index 7213c4e0..7f073a0f 100644 --- a/butane_core/src/lib.rs +++ b/butane_core/src/lib.rs @@ -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; + /// 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; } } @@ -148,7 +148,7 @@ pub trait DataObject: DataResult + 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 @@ -156,13 +156,18 @@ pub trait DataObject: DataResult + internal::DataObjectInternal { 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)?; diff --git a/butane_core/src/migrations/mod.rs b/butane_core/src/migrations/mod.rs index 4dcdd42e..a0ce065e 100644 --- a/butane_core/src/migrations/mod.rs +++ b/butane_core/src/migrations/mod.rs @@ -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 { + fn non_auto_values(&self, include_pk: bool) -> Vec { let mut values: Vec> = Vec::with_capacity(2usize); if include_pk { values.push(self.name.to_sql_ref());