From 2fbba1bcd1511491f049f4f872551a67ddae42ad Mon Sep 17 00:00:00 2001 From: Ryan Levick Date: Wed, 25 Oct 2023 16:13:35 +0200 Subject: [PATCH] Improve the outparam API Signed-off-by: Ryan Levick --- .../src/lib.rs | 16 ++++++------- sdk/rust/macro/src/lib.rs | 6 ++--- sdk/rust/src/http.rs | 23 +++++++++++++++++-- sdk/rust/src/http/conversions.rs | 6 ++--- 4 files changed, 33 insertions(+), 18 deletions(-) diff --git a/examples/wasi-http-rust-streaming-outgoing-body/src/lib.rs b/examples/wasi-http-rust-streaming-outgoing-body/src/lib.rs index e12e65757f..70070ca199 100644 --- a/examples/wasi-http-rust-streaming-outgoing-body/src/lib.rs +++ b/examples/wasi-http-rust-streaming-outgoing-body/src/lib.rs @@ -2,7 +2,7 @@ use anyhow::{bail, Result}; use futures::{stream, SinkExt, StreamExt, TryStreamExt}; use spin_sdk::http::send; use spin_sdk::http::{ - Fields, IncomingRequest, IncomingResponse, Method, OutgoingBody, OutgoingRequest, + Headers, IncomingRequest, IncomingResponse, Method, OutgoingBody, OutgoingRequest, OutgoingResponse, ResponseOutparam, Scheme, }; use spin_sdk::http_component; @@ -32,12 +32,12 @@ async fn handle_request(request: IncomingRequest, response_out: ResponseOutparam let response = OutgoingResponse::new( 200, - &Fields::new(&[("content-type".to_string(), b"text/plain".to_vec())]), + &Headers::new(&[("content-type".to_string(), b"text/plain".to_vec())]), ); let mut body = response.take_body(); - ResponseOutparam::set(response_out, Ok(response)); + response_out.set(response); while let Some((url, result)) = results.next().await { let payload = match result { @@ -54,7 +54,7 @@ async fn handle_request(request: IncomingRequest, response_out: ResponseOutparam (Method::Post, Some("/echo")) => { let response = OutgoingResponse::new( 200, - &Fields::new( + &Headers::new( &headers .into_iter() .filter_map(|(k, v)| (k == "content-type").then_some((k, v))) @@ -64,7 +64,7 @@ async fn handle_request(request: IncomingRequest, response_out: ResponseOutparam let mut body = response.take_body(); - ResponseOutparam::set(response_out, Ok(response)); + response_out.set(response); let mut stream = request.into_body_stream(); while let Some(chunk) = stream.next().await { @@ -84,11 +84,11 @@ async fn handle_request(request: IncomingRequest, response_out: ResponseOutparam } _ => { - let response = OutgoingResponse::new(405, &Fields::new(&[])); + let response = OutgoingResponse::new(405, &Headers::new(&[])); let body = response.write().expect("response should be writable"); - ResponseOutparam::set(response_out, Ok(response)); + response_out.set(response); OutgoingBody::finish(body, None); } @@ -105,7 +105,7 @@ async fn hash(url: &Url) -> Result { scheme => Scheme::Other(scheme.into()), }), Some(url.authority()), - &Fields::new(&[]), + &Headers::new(&[]), ); let response: IncomingResponse = send(request).await?; diff --git a/sdk/rust/macro/src/lib.rs b/sdk/rust/macro/src/lib.rs index 03e84ff5a3..dbf6b20367 100644 --- a/sdk/rust/macro/src/lib.rs +++ b/sdk/rust/macro/src/lib.rs @@ -121,8 +121,7 @@ pub fn http_component(_attr: TokenStream, item: TokenStream) -> TokenStream { impl From for ::spin_sdk::http::IncomingRequest { fn from(req: self::wasi::http::types::IncomingRequest) -> Self { - let req = ::std::mem::ManuallyDrop::new(req); - unsafe { Self::from_handle(req.handle()) } + unsafe { Self::from_handle(req.into_handle()) } } } @@ -134,8 +133,7 @@ pub fn http_component(_attr: TokenStream, item: TokenStream) -> TokenStream { impl From for ::spin_sdk::http::ResponseOutparam { fn from(resp: self::wasi::http::types::ResponseOutparam) -> Self { - let resp = ::std::mem::ManuallyDrop::new(resp); - unsafe { Self::from_handle(resp.handle()) } + unsafe { Self::from_handle(resp.into_handle()) } } } } diff --git a/sdk/rust/src/http.rs b/sdk/rust/src/http.rs index 8e912e9e43..93f7db64cb 100644 --- a/sdk/rust/src/http.rs +++ b/sdk/rust/src/http.rs @@ -6,8 +6,12 @@ pub use conversions::IntoResponse; use self::conversions::TryFromIncomingResponse; +use super::wit::wasi::http::types; #[doc(inline)] -pub use super::wit::wasi::http::types::*; +pub use types::{ + Error, Fields, Headers, IncomingRequest, IncomingResponse, Method, OutgoingBody, + OutgoingRequest, OutgoingResponse, Scheme, StatusCode, Trailers, +}; /// A unified request object that can represent both incoming and outgoing requests. /// @@ -153,7 +157,22 @@ impl OutgoingResponse { } } +/// The out param for setting an `OutgoingResponse` +pub struct ResponseOutparam(types::ResponseOutparam); + impl ResponseOutparam { + #[doc(hidden)] + // This is needed for the macro so we can transfrom the macro's + // `ResponseOutparam` to this `ResponseOutparam` + pub unsafe fn from_handle(handle: u32) -> Self { + Self(types::ResponseOutparam::from_handle(handle)) + } + + /// Set the outgoing response + pub fn set(self, response: OutgoingResponse) { + types::ResponseOutparam::set(self.0, Ok(response)); + } + /// Set with the outgoing response and the supplied buffer /// /// Will panic if response body has already been taken @@ -164,7 +183,7 @@ impl ResponseOutparam { ) -> anyhow::Result<()> { use futures::SinkExt; let mut body = response.take_body(); - ResponseOutparam::set(self, Ok(response)); + self.set(response); body.send(buffer).await } } diff --git a/sdk/rust/src/http/conversions.rs b/sdk/rust/src/http/conversions.rs index bc4ec78617..6948fb91a7 100644 --- a/sdk/rust/src/http/conversions.rs +++ b/sdk/rust/src/http/conversions.rs @@ -1,8 +1,6 @@ use async_trait::async_trait; -use super::{ - Fields, Headers, IncomingRequest, IncomingResponse, OutgoingRequest, OutgoingResponse, -}; +use super::{Headers, IncomingRequest, IncomingResponse, OutgoingRequest, OutgoingResponse}; use super::{responses, NonUtf8BodyError, Request, Response}; @@ -466,7 +464,7 @@ where }) .as_ref(), req.uri().authority().map(|a| a.as_str()), - &Fields::new(&headers), + &Headers::new(&headers), )) } }