diff --git a/test/src/d1.rs b/test/src/d1.rs index a38c3625..519deeb9 100644 --- a/test/src/d1.rs +++ b/test/src/d1.rs @@ -297,7 +297,8 @@ pub async fn insert_and_retrieve_optional_none( &None::, &None:: )?; - query.run().await?; + // Run the insert by awaiting the statement directly (exercises IntoFuture). + query.await?; let stmt = worker::query!(&db, "SELECT * FROM nullable_people WHERE id = 3"); let person = stmt.first::(None).await?.unwrap(); diff --git a/worker/src/d1/mod.rs b/worker/src/d1/mod.rs index e29f0044..47799065 100644 --- a/worker/src/d1/mod.rs +++ b/worker/src/d1/mod.rs @@ -1,7 +1,9 @@ use std::fmt::Display; use std::fmt::Formatter; +use std::future::{Future, IntoFuture}; use std::iter::{once, Once}; use std::ops::Deref; +use std::pin::Pin; use std::result::Result as StdResult; use js_sys::futures::JsFuture; @@ -332,6 +334,7 @@ impl D1Argument for D1PreparedArgument<'_> { // A D1 prepared query statement. #[derive(Debug, Clone)] +#[must_use = "D1PreparedStatement does nothing until you run or await it"] pub struct D1PreparedStatement(D1PreparedStatementSys); impl D1PreparedStatement { @@ -445,6 +448,17 @@ impl D1PreparedStatement { } } +impl IntoFuture for D1PreparedStatement { + type Output = Result; + type IntoFuture = Pin>>; + + /// Awaiting runs the statement via [`run`](D1PreparedStatement::run) and returns only metadata. + /// Use [`all`](D1PreparedStatement::all) or [`first`](D1PreparedStatement::first) to retrieve rows. + fn into_future(self) -> Self::IntoFuture { + Box::pin(async move { self.run().await }) + } +} + impl From for D1PreparedStatement { fn from(inner: D1PreparedStatementSys) -> Self { Self(inner) @@ -588,3 +602,18 @@ mod tests { ); } } + +#[cfg(test)] +mod into_future_check { + // Awaiting a statement resolves through `run`, so the impl must yield + // `Result`. This compile-time check guards that contract. + use super::{D1PreparedStatement, D1Result}; + use crate::Result; + use std::future::IntoFuture; + + fn _assert_into_future>>() {} + #[allow(dead_code)] + fn _check() { + _assert_into_future::(); + } +}