Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion test/src/d1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,8 @@ pub async fn insert_and_retrieve_optional_none(
&None::<String>,
&None::<u32>
)?;
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::<NullablePerson>(None).await?.unwrap();
Expand Down
29 changes: 29 additions & 0 deletions worker/src/d1/mod.rs
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -445,6 +448,17 @@ impl D1PreparedStatement {
}
}

impl IntoFuture for D1PreparedStatement {
type Output = Result<D1Result>;
type IntoFuture = Pin<Box<dyn Future<Output = Self::Output>>>;

/// 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<D1PreparedStatementSys> for D1PreparedStatement {
fn from(inner: D1PreparedStatementSys) -> Self {
Self(inner)
Expand Down Expand Up @@ -588,3 +602,18 @@ mod tests {
);
}
}

#[cfg(test)]
mod into_future_check {
// Awaiting a statement resolves through `run`, so the impl must yield
// `Result<D1Result>`. This compile-time check guards that contract.
use super::{D1PreparedStatement, D1Result};
use crate::Result;
use std::future::IntoFuture;

fn _assert_into_future<T: IntoFuture<Output = Result<D1Result>>>() {}
#[allow(dead_code)]
fn _check() {
_assert_into_future::<D1PreparedStatement>();
}
}
Loading