1- //! Experimental Rust SDK for wasip3 http.
1+ //! Experimental Rust SDK for WASIp3 http.
22
33#![ deny( missing_docs) ]
44
55#[ doc( hidden) ]
6- pub use wasip3;
6+ pub use wasip3_http_ext :: wasip3;
77
88use hyperium as http;
99use std:: any:: Any ;
@@ -16,33 +16,86 @@ use wasip3_http_ext::helpers::{
1616use wasip3_http_ext:: RequestOptionsExtension ;
1717use wasip3_http_ext:: { IncomingRequestBody , IncomingResponseBody } ;
1818
19+ /// A body type representing an empty payload.
20+ ///
21+ /// This is a convenience alias for [`http_body_util::Empty<bytes::Bytes>`],
22+ /// used when constructing HTTP requests or responses with no body.
23+ ///
24+ /// # Examples
25+ ///
26+ /// ```rust
27+ /// use crate::EmptyBody;
28+ ///
29+ /// let empty = EmptyBody::new();
30+ /// let response = http::Response::builder()
31+ /// .status(204)
32+ /// .body(empty)
33+ /// .unwrap();
34+ /// ```
35+ pub type EmptyBody = http_body_util:: Empty < bytes:: Bytes > ;
36+
37+ /// A body type representing a complete, in-memory payload.
38+ ///
39+ /// This is a convenience alias for [`http_body_util::Full<T>`], used when the
40+ /// entire body is already available as a single value of type `T`.
41+ ///
42+ /// It is typically used for sending small or pre-buffered request or response
43+ /// bodies without the need for streaming.
44+ ///
45+ /// # Type Parameters
46+ ///
47+ /// * `T` — The data type of the full body, such as [`bytes::Bytes`] or [`String`].
48+ ///
49+ /// # Examples
50+ ///
51+ /// ```rust
52+ /// use crate::FullBody;
53+ /// use bytes::Bytes;
54+ ///
55+ /// let body = FullBody::new(Bytes::from("hello"));
56+ /// let request = http::Request::builder()
57+ /// .method("POST")
58+ /// .uri("https://example.com")
59+ /// .body(body)
60+ /// .unwrap();
61+ /// ```
62+ pub type FullBody < T > = http_body_util:: Full < T > ;
63+
1964/// A alias for [`std::result::Result`] that uses [`Error`] as the default error type.
2065///
2166/// This allows functions throughout the crate to return `Result<T>`
2267/// instead of writing out `Result<T, Error>` explicitly.
2368pub type Result < T , E = Error > = :: std:: result:: Result < T , E > ;
2469
25- /// An inbound HTTP request carrying an [`wasip3_http_ext::IncomingRequestBody`].
70+ /// A type alias for an HTTP request with a customizable body type.
71+ ///
72+ /// This is a convenience wrapper around [`http::Request`], parameterized
73+ /// by the body type `T`. By default, it uses [`IncomingRequestBody`],
74+ /// which represents the standard incoming body used by this runtime.
75+ ///
76+ /// # Type Parameters
2677///
27- /// This type alias specializes [`http::Request`] with the crate’s
28- /// [`wasip3_http_ext::IncomingRequestBody`] type, representing a request received
29- /// from the WASI HTTP runtime or an external client.
78+ /// * `T` — The request body type. Defaults to [`IncomingRequestBody`].
3079///
3180/// # See also
3281/// - [`wasip3_http_ext::IncomingRequestBody`]: The body type for inbound HTTP requests.
3382/// - [`http::Request`]: The standard HTTP request type from the `http` crate.
34- pub type IncomingRequest = http:: Request < IncomingRequestBody > ;
83+ pub type Request < T = IncomingRequestBody > = http:: Request < T > ;
3584
36- /// An inbound HTTP response carrying an [`wasip3_http_ext::IncomingResponseBody`] .
85+ /// A type alias for an HTTP response with a customizable body type .
3786///
38- /// This type alias specializes [`http::Response`] with the crate’s
39- /// [`wasip3_http_ext::IncomingResponseBody`] type, representing a response received
40- /// from the WASI HTTP runtime or a remote endpoint.
87+ /// This is a convenience wrapper around [`http::Response`], parameterized
88+ /// by the body type `T`. By default, it uses [`IncomingResponseBody`],
89+ /// which represents the standard incoming body type used by this runtime.
90+ ///
91+ /// # Type Parameters
92+ ///
93+ /// * `T` — The response body type. Defaults to [`IncomingResponseBody`].
4194///
4295/// # See also
4396/// - [`wasip3_http_ext::IncomingResponseBody`]: The body type for inbound HTTP responses.
4497/// - [`http::Response`]: The standard HTTP response type from the `http` crate.
45- pub type IncomingResponse = http:: Response < IncomingResponseBody > ;
98+ pub type Response < T = IncomingResponseBody > = http:: Response < T > ;
4699
47100type HttpResult < T > = Result < T , types:: ErrorCode > ;
48101
@@ -52,10 +105,10 @@ type HttpResult<T> = Result<T, types::ErrorCode>;
52105/// [`IntoRequest`] trait, dispatches it to the WASI HTTP handler, and awaits
53106/// the resulting response. It provides a convenient high-level interface for
54107/// issuing HTTP requests within a WASI environment.
55- pub async fn send ( request : impl IntoRequest ) -> HttpResult < IncomingResponse > {
108+ pub async fn send ( request : impl IntoRequest ) -> HttpResult < Response > {
56109 let request = request. into_request ( ) ?;
57110 let response = wasip3:: http:: handler:: handle ( request) . await ?;
58- IncomingResponse :: from_response ( response)
111+ Response :: from_response ( response)
59112}
60113
61114/// A trait for any type that can be converted into a [`wasip3::http::types::Request`].
@@ -415,3 +468,57 @@ impl FromResponse for IncomingResponseBody {
415468 Self :: new ( response)
416469 }
417470}
471+
472+ /// Helpers for consuming an [`IncomingBody`].
473+ ///
474+ /// This module provides extension traits and utilities for working with
475+ /// [`IncomingBody`] instances, such as streaming or collecting the entire
476+ /// body into memory.
477+ ///
478+ /// These helpers make it easier to transform low-level streaming body types
479+ /// into higher-level forms (e.g., [`Bytes`]) for simplified data handling.
480+ pub mod body {
481+ use bytes:: Bytes ;
482+ use http_body_util:: { BodyDataStream , BodyExt } ;
483+ use wasip3_http_ext:: wasip3:: http:: types:: ErrorCode ;
484+ use wasip3_http_ext:: { IncomingBody , IncomingMessage } ;
485+
486+ /// Extension trait providing convenient methods for consuming an [`IncomingBody`].
487+ ///
488+ /// This trait defines common patterns for handling HTTP body data in
489+ /// asynchronous contexts. It allows converting the body into a stream
490+ /// or fully collecting it into memory as a [`Bytes`] buffer.
491+ #[ allow( async_fn_in_trait) ]
492+ pub trait IncomingBodyExt {
493+ /// Convert this [`IncomingBody`] into a [`BodyDataStream`].
494+ ///
495+ /// This method enables iteration over the body’s data chunks as they
496+ /// arrive, without collecting them all into memory at once. It is
497+ /// suitable for processing large or streaming payloads efficiently.
498+ fn stream ( self ) -> BodyDataStream < Self >
499+ where
500+ Self : Sized ;
501+
502+ /// Consume this [`IncomingBody`] and collect it into a single [`Bytes`] buffer.
503+ ///
504+ /// This method reads the entire body asynchronously and returns the
505+ /// concatenated contents. It is best suited for small or bounded-size
506+ /// payloads where holding all data in memory is acceptable.
507+ async fn bytes ( self ) -> Result < Bytes , ErrorCode > ;
508+ }
509+
510+ impl < T : IncomingMessage > IncomingBodyExt for IncomingBody < T > {
511+ /// Convert this [`IncomingBody`] into a [`BodyDataStream`].
512+ fn stream ( self ) -> BodyDataStream < Self >
513+ where
514+ Self : Sized ,
515+ {
516+ BodyDataStream :: new ( self )
517+ }
518+
519+ /// Collect the [`IncomingBody`] into a single [`Bytes`] buffer.
520+ async fn bytes ( self ) -> Result < Bytes , ErrorCode > {
521+ self . collect ( ) . await . map ( |c| c. to_bytes ( ) )
522+ }
523+ }
524+ }
0 commit comments