diff --git a/cot-macros/src/model.rs b/cot-macros/src/model.rs index 91006c40..28135814 100644 --- a/cot-macros/src/model.rs +++ b/cot-macros/src/model.rs @@ -160,7 +160,6 @@ impl ModelBuilder { #[must_use] fn build_model_impl(&self) -> TokenStream { - let crate_ident = cot_ident(); let orm_ident = orm_ident(); let name = &self.name; @@ -176,7 +175,6 @@ impl ModelBuilder { let fields_as_get_values = &self.fields_as_get_values; quote! { - #[#crate_ident::__private::async_trait] #[automatically_derived] impl #orm_ident::Model for #name { type Fields = #fields_struct_name; diff --git a/cot/src/auth/db.rs b/cot/src/auth/db.rs index 8eb6190f..0a3083f5 100644 --- a/cot/src/auth/db.rs +++ b/cot/src/auth/db.rs @@ -615,7 +615,7 @@ mod tests { let mut mock_db = MockDatabaseBackend::new(); mock_db .expect_insert::() - .returning(|_| Ok(())); + .returning(|_| Box::pin(async { Ok(()) })); let username = "testuser".to_string(); let password = Password::new("password123"); @@ -636,9 +636,10 @@ mod tests { &Password::new("password123"), ); - mock_db - .expect_get::() - .returning(move |_| Ok(Some(user.clone()))); + mock_db.expect_get::().returning(move |_| { + let user = user.clone(); + Box::pin(async move { Ok(Some(user.clone())) }) + }); let result = DatabaseUser::get_by_id(&mock_db, 1).await.unwrap(); assert!(result.is_some()); @@ -655,9 +656,10 @@ mod tests { &Password::new("password123"), ); - mock_db - .expect_get::() - .returning(move |_| Ok(Some(user.clone()))); + mock_db.expect_get::().returning(move |_| { + let user = user.clone(); + Box::pin(async move { Ok(Some(user.clone())) }) + }); let credentials = DatabaseUserCredentials::new("testuser".to_string(), Password::new("password123")); @@ -675,7 +677,7 @@ mod tests { mock_db .expect_get::() - .returning(move |_| Ok(None)); + .returning(|_| Box::pin(async { Ok(None) })); let credentials = DatabaseUserCredentials::new("testuser".to_string(), Password::new("password123")); @@ -695,9 +697,10 @@ mod tests { &Password::new("password123"), ); - mock_db - .expect_get::() - .returning(move |_| Ok(Some(user.clone()))); + mock_db.expect_get::().returning(move |_| { + let user = user.clone(); + Box::pin(async move { Ok(Some(user.clone())) }) + }); let credentials = DatabaseUserCredentials::new("testuser".to_string(), Password::new("invalid")); diff --git a/cot/src/db.rs b/cot/src/db.rs index 445dd972..6d18af8d 100644 --- a/cot/src/db.rs +++ b/cot/src/db.rs @@ -20,7 +20,6 @@ use std::hash::Hash; use std::str::FromStr; use std::sync::Arc; -use async_trait::async_trait; use cot_core::error::impl_into_cot_error; pub use cot_macros::{model, query}; use derive_more::{Debug, Deref, Display}; @@ -151,7 +150,6 @@ pub type Result = std::result::Result; /// name: String, /// } /// ``` -#[async_trait] #[diagnostic::on_unimplemented( message = "`{Self}` is not marked as a database model", label = "`{Self}` is not annotated with `#[cot::db::model]`", @@ -228,10 +226,10 @@ pub trait Model: Sized + Send + 'static { /// This method can return an error if the model instance could not be /// found in the database, or there was a problem with the database /// connection. - async fn get_by_primary_key( + fn get_by_primary_key( db: &DB, pk: Self::PrimaryKey, - ) -> Result>; + ) -> impl Future>>; /// Inserts the model instance to the database, or updates an instance /// with the same primary key if it already exists. @@ -245,9 +243,8 @@ pub trait Model: Sized + Send + 'static { /// inserted into the database, for instance because the migrations /// haven't been applied, or there was a problem with the database /// connection. - async fn save(&mut self, db: &DB) -> Result<()> { - db.insert_or_update(self).await?; - Ok(()) + fn save(&mut self, db: &DB) -> impl Future> { + async move { db.insert_or_update(self).await } } /// Insert the model instance to the database. @@ -258,9 +255,8 @@ pub trait Model: Sized + Send + 'static { /// inserted into the database, for instance because the migrations /// haven't been applied, or there was a problem with the database /// connection. - async fn insert(&mut self, db: &DB) -> Result<()> { - db.insert(self).await?; - Ok(()) + fn insert(&mut self, db: &DB) -> impl Future> { + async move { db.insert(self).await } } /// Update the model instance in the database. @@ -274,9 +270,8 @@ pub trait Model: Sized + Send + 'static { /// /// This method can return an error if the model with the given primary key /// could not be found in the database. - async fn update(&mut self, db: &DB) -> Result<()> { - db.update(self).await?; - Ok(()) + fn update(&mut self, db: &DB) -> impl Future> { + async move { db.update(self).await } } /// Bulk insert multiple model instances to the database in a single query. @@ -318,9 +313,11 @@ pub trait Model: Sized + Send + 'static { /// // After insertion, all todos have populated IDs /// assert!(todos[0].id.is_fixed()); /// ``` - async fn bulk_insert(db: &DB, instances: &mut [Self]) -> Result<()> { - db.bulk_insert(instances).await?; - Ok(()) + fn bulk_insert( + db: &DB, + instances: &mut [Self], + ) -> impl Future> { + async move { db.bulk_insert(instances).await } } /// Bulk insert multiple model instances to the database in a single query, @@ -357,12 +354,11 @@ pub trait Model: Sized + Send + 'static { /// // After insertion, all todos have populated IDs /// assert!(todos[0].id.is_fixed()); /// ``` - async fn bulk_insert_or_update( + fn bulk_insert_or_update( db: &DB, instances: &mut [Self], - ) -> Result<()> { - db.bulk_insert_or_update(instances).await?; - Ok(()) + ) -> impl Future> { + async move { db.bulk_insert_or_update(instances).await } } } @@ -1590,7 +1586,6 @@ impl ColumnTypeMapper for Database { /// /// This trait is used to provide a backend for the database. #[cfg_attr(test, automock)] -#[async_trait] pub trait DatabaseBackend: Send + Sync { /// Inserts a new row into the database, or updates an existing row if it /// already exists. @@ -1600,7 +1595,7 @@ pub trait DatabaseBackend: Send + Sync { /// This method can return an error if the row could not be inserted into /// the database, for instance because the migrations haven't been /// applied, or there was a problem with the database connection. - async fn insert_or_update(&self, data: &mut T) -> Result<()>; + fn insert_or_update(&self, data: &mut T) -> impl Future>; /// Inserts a new row into the database. /// @@ -1609,7 +1604,7 @@ pub trait DatabaseBackend: Send + Sync { /// This method can return an error if the row could not be inserted into /// the database, for instance because the migrations haven't been /// applied, or there was a problem with the database connection. - async fn insert(&self, data: &mut T) -> Result<()>; + fn insert(&self, data: &mut T) -> impl Future>; /// Updates an existing row in the database. /// @@ -1618,7 +1613,7 @@ pub trait DatabaseBackend: Send + Sync { /// This method can return an error if the row could not be updated in the /// database, for instance because the migrations haven't been applied, or /// there was a problem with the database connection. - async fn update(&self, data: &mut T) -> Result<()>; + fn update(&self, data: &mut T) -> impl Future>; /// Bulk inserts multiple rows into the database. /// @@ -1627,7 +1622,7 @@ pub trait DatabaseBackend: Send + Sync { /// This method can return an error if the rows could not be inserted into /// the database, for instance because the migrations haven't been /// applied, or there was a problem with the database connection. - async fn bulk_insert(&self, data: &mut [T]) -> Result<()>; + fn bulk_insert(&self, data: &mut [T]) -> impl Future>; /// Bulk inserts multiple rows into the database, or updates existing rows /// if they already exist. @@ -1637,7 +1632,7 @@ pub trait DatabaseBackend: Send + Sync { /// This method can return an error if the rows could not be inserted into /// the database, for instance because the migrations haven't been /// applied, or there was a problem with the database connection. - async fn bulk_insert_or_update(&self, data: &mut [T]) -> Result<()>; + fn bulk_insert_or_update(&self, data: &mut [T]) -> impl Future>; /// Executes a query and returns the results converted to the model type. /// @@ -1650,7 +1645,7 @@ pub trait DatabaseBackend: Send + Sync { /// generated or applied). /// /// Can return an error if the database connection is lost. - async fn query(&self, query: &Query) -> Result>; + fn query(&self, query: &Query) -> impl Future>>; /// Returns the first row that matches the given query. If no rows match the /// query, returns `None`. @@ -1664,7 +1659,7 @@ pub trait DatabaseBackend: Send + Sync { /// applied). /// /// Can return an error if the database connection is lost. - async fn get(&self, query: &Query) -> Result>; + fn get(&self, query: &Query) -> impl Future>>; /// Returns whether a row exists that matches the given query. /// @@ -1677,7 +1672,7 @@ pub trait DatabaseBackend: Send + Sync { /// applied). /// /// Can return an error if the database connection is lost. - async fn exists(&self, query: &Query) -> Result; + fn exists(&self, query: &Query) -> impl Future>; /// Deletes all rows that match the given query. /// @@ -1690,10 +1685,9 @@ pub trait DatabaseBackend: Send + Sync { /// applied). /// /// Can return an error if the database connection is lost. - async fn delete(&self, query: &Query) -> Result; + fn delete(&self, query: &Query) -> impl Future>; } -#[async_trait] impl DatabaseBackend for Database { async fn insert_or_update(&self, data: &mut T) -> Result<()> { Database::insert_or_update(self, data).await diff --git a/cot/src/db/query.rs b/cot/src/db/query.rs index 139a7ca7..1ae5c239 100644 --- a/cot/src/db/query.rs +++ b/cot/src/db/query.rs @@ -1481,7 +1481,8 @@ mod tests { #[cot::test] async fn query_all() { let mut db = MockDatabaseBackend::new(); - db.expect_query().returning(|_| Ok(Vec::::new())); + db.expect_query() + .returning(|_| Box::pin(async { Ok(Vec::::new()) })); let query: Query = Query::new(); let result = query.all(&db).await; @@ -1492,7 +1493,8 @@ mod tests { #[cot::test] async fn query_get() { let mut db = MockDatabaseBackend::new(); - db.expect_get().returning(|_| Ok(Option::::None)); + db.expect_get() + .returning(|_| Box::pin(async { Ok(Option::::None) })); let query: Query = Query::new(); let result = query.get(&db).await; @@ -1504,7 +1506,7 @@ mod tests { async fn query_exists() { let mut db = MockDatabaseBackend::new(); db.expect_exists() - .returning(|_: &Query| Ok(false)); + .returning(|_: &Query| Box::pin(async { Ok(false) })); let query: Query = Query::new(); @@ -1515,8 +1517,9 @@ mod tests { #[cot::test] async fn query_delete() { let mut db = MockDatabaseBackend::new(); - db.expect_delete() - .returning(|_: &Query| Ok(StatementResult::new(RowsNum(0)))); + db.expect_delete().returning(|_: &Query| { + Box::pin(async { Ok(StatementResult::new(RowsNum(0))) }) + }); let query: Query = Query::new(); let result = query.delete(&db).await; diff --git a/cot/src/lib.rs b/cot/src/lib.rs index 22ea64d5..cc11ba1a 100644 --- a/cot/src/lib.rs +++ b/cot/src/lib.rs @@ -84,7 +84,6 @@ pub(crate) mod utils; #[cfg(feature = "openapi")] pub use aide; -pub use bytes; /// A wrapper around a handler that's used in [`Bootstrapper`]. /// /// It is returned by [`Bootstrapper::finish`]. Typically, you don't need to @@ -182,9 +181,9 @@ pub use cot_macros::e2e_test; /// ``` pub use cot_macros::main; pub use cot_macros::test; -pub use http; #[cfg(feature = "openapi")] pub use schemars; +pub use {bytes, http}; pub use crate::__private::askama::{Template, filter_fn}; pub use crate::project::{