From a4ee1956e0476f11776fb5a172a84d39e445cfae Mon Sep 17 00:00:00 2001 From: David Herberth Date: Tue, 26 Nov 2024 12:22:45 +0100 Subject: [PATCH 1/3] ref(develop): Update Rust async trait section --- develop-docs/engineering-practices/rust.mdx | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/develop-docs/engineering-practices/rust.mdx b/develop-docs/engineering-practices/rust.mdx index 8118e62c79d1f..aafc685921c04 100644 --- a/develop-docs/engineering-practices/rust.mdx +++ b/develop-docs/engineering-practices/rust.mdx @@ -50,26 +50,20 @@ During migration you may need normal functions which return futures, for their s ### Async Traits -In **traits** you can not yet use `async fn` ([see this blog post](https://smallcultfollowing.com/babysteps/blog/2019/10/26/async-fn-in-traits-are-hard/)). -In this case, functions should return `-> Pin + Send>>`: +Support for async in **traits** has [landed in Rust](https://blog.rust-lang.org/2023/12/21/async-fn-rpit-in-traits.html) +and should generally be preferred now. ```rust -trait Database { - fn get_user(&self) -> Pin + Send + '_>>; -} - -impl Database for MyDB { - fn get_user(&self) -> Pin + Send + '_>> { - Box::pin(async { - // ... - }) - } +pub trait Databse { + fn get_user(&self) -> impl Future + Send; } ``` Note that the returned future type is `Send`, to ensure that it can run on a multi-threaded runtime. -This corresponds to what the [async-trait crate](https://crates.io/crates/async-trait) does. +When you need dynamic dispatch or have to support Rust versions older than 1.75 consider using the +[`async-trait`](https://docs.rs/async-trait/) crate. + ### Avoid `.unwrap()` From 158eaba3d2edab63e8595946bf442af9ff320eed Mon Sep 17 00:00:00 2001 From: David Herberth Date: Tue, 26 Nov 2024 12:43:10 +0100 Subject: [PATCH 2/3] Update develop-docs/engineering-practices/rust.mdx Co-authored-by: Riccardo Busetti --- develop-docs/engineering-practices/rust.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/develop-docs/engineering-practices/rust.mdx b/develop-docs/engineering-practices/rust.mdx index aafc685921c04..ae808096b16d7 100644 --- a/develop-docs/engineering-practices/rust.mdx +++ b/develop-docs/engineering-practices/rust.mdx @@ -54,7 +54,7 @@ Support for async in **traits** has [landed in Rust](https://blog.rust-lang.org/ and should generally be preferred now. ```rust -pub trait Databse { +pub trait Database { fn get_user(&self) -> impl Future + Send; } ``` From e6b9e77c2d1e11dd7012e1a717e3fe2529d190f0 Mon Sep 17 00:00:00 2001 From: David Herberth Date: Tue, 26 Nov 2024 13:04:19 +0100 Subject: [PATCH 3/3] add trait impl back in --- develop-docs/engineering-practices/rust.mdx | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/develop-docs/engineering-practices/rust.mdx b/develop-docs/engineering-practices/rust.mdx index ae808096b16d7..aa1cae45b40fb 100644 --- a/develop-docs/engineering-practices/rust.mdx +++ b/develop-docs/engineering-practices/rust.mdx @@ -57,6 +57,12 @@ and should generally be preferred now. pub trait Database { fn get_user(&self) -> impl Future + Send; } + +impl Database for MyDatabase { + async fn get_user(&self) -> User { + todo!() + } +} ``` Note that the returned future type is `Send`, to ensure that it can run on a multi-threaded runtime.