Skip to content

Commit

Permalink
feat(wasm): add wasm32-wasip2 stable support
Browse files Browse the repository at this point in the history
Signed-off-by: Brooks Townsend <brooksmtownsend@gmail.com>

cleanup extraneous comment

Signed-off-by: Brooks Townsend <brooksmtownsend@gmail.com>

feat: give back incoming body too

Signed-off-by: Brooks Townsend <brooksmtownsend@gmail.com>
  • Loading branch information
brooksmtownsend committed Oct 21, 2024
1 parent 344179b commit 2cad7e9
Show file tree
Hide file tree
Showing 8 changed files with 1,012 additions and 1 deletion.
8 changes: 8 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,9 @@ wasm-bindgen = "0.2.68"
wasm-bindgen-futures = "0.4.18"
wasm-streams = { version = "0.4", optional = true }

[target.'cfg(all(target_os = "wasi", target_env = "p2"))'.dependencies]
wasi = "=0.13.3" # For compatibility, pin to wasi@0.2.2 bindings

[target.'cfg(target_arch = "wasm32")'.dependencies.web-sys]
version = "0.3.28"
features = [
Expand Down Expand Up @@ -284,3 +287,8 @@ required-features = ["deflate", "stream"]
name = "multipart"
path = "tests/multipart.rs"
required-features = ["multipart"]

# https://github.com/servo/rust-url/pull/983
[patch.crates-io]
url = { git = "https://github.com/servo/rust-url", rev = "fc447cce1d2c06ef0bec3dbadce56b83e46ca1ff"}
form_urlencoded = { git = "https://github.com/servo/rust-url", rev = "fc447cce1d2c06ef0bec3dbadce56b83e46ca1ff"}
34 changes: 33 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -306,10 +306,42 @@ pub use self::response::ResponseBuilderExt;
/// - supplied `Url` cannot be parsed
/// - there was an error while sending request
/// - redirect limit was exhausted
#[cfg(not(any(target_os = "wasi", target_env = "p2")))]
pub async fn get<T: IntoUrl>(url: T) -> crate::Result<Response> {
Client::builder().build()?.get(url).send().await
}

/// Shortcut method to quickly make a `GET` request.
///
/// See also the methods on the [`reqwest::Response`](./struct.Response.html)
/// type.
///
/// **NOTE**: This function creates a new internal `Client` on each call,
/// and so should not be used if making many requests. Create a
/// [`Client`](./struct.Client.html) instead.
///
/// # Examples
///
/// ```rust
/// # fn run() -> Result<(), reqwest::Error> {
/// let body = reqwest::get("https://www.rust-lang.org")?
/// .text()?;
/// # Ok(())
/// # }
/// ```
///
/// # Errors
///
/// This function fails if:
///
/// - supplied `Url` cannot be parsed
/// - there was an error while sending request
/// - redirect limit was exhausted
#[cfg(all(target_os = "wasi", target_env = "p2"))]
pub fn get<T: IntoUrl>(url: T) -> crate::Result<Response> {
Client::builder().build()?.get(url).send()
}

fn _assert_impls() {
fn assert_send<T: Send>() {}
fn assert_sync<T: Sync>() {}
Expand Down Expand Up @@ -372,6 +404,6 @@ if_wasm! {
mod util;

pub use self::wasm::{Body, Client, ClientBuilder, Request, RequestBuilder, Response};
#[cfg(feature = "multipart")]
#[cfg(all(not(all(target_os = "wasi", target_env = "p2")), feature = "multipart"))]
pub use self::wasm::multipart;
}
111 changes: 111 additions & 0 deletions src/wasm/component/body.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
use bytes::Bytes;
use std::{borrow::Cow, fmt};

/// The body of a [`super::Request`].
pub struct Body {
inner: Inner,
}

enum Inner {
Single(Single),
}

#[derive(Clone)]
pub(crate) enum Single {
Bytes(Bytes),
Text(Cow<'static, str>),
}

impl Single {
fn as_bytes(&self) -> &[u8] {
match self {
Single::Bytes(bytes) => bytes.as_ref(),
Single::Text(text) => text.as_bytes(),
}
}

fn is_empty(&self) -> bool {
match self {
Single::Bytes(bytes) => bytes.is_empty(),
Single::Text(text) => text.is_empty(),
}
}
}

impl Body {
/// Returns a reference to the internal data of the `Body`.
///
/// `None` is returned, if the underlying data is a multipart form.
#[inline]
pub fn as_bytes(&self) -> Option<&[u8]> {
match &self.inner {
Inner::Single(single) => Some(single.as_bytes()),
}
}

#[allow(unused)]
pub(crate) fn is_empty(&self) -> bool {
match &self.inner {
Inner::Single(single) => single.is_empty(),
}
}

pub(crate) fn try_clone(&self) -> Option<Body> {
match &self.inner {
Inner::Single(single) => Some(Self {
inner: Inner::Single(single.clone()),
}),
}
}
}

impl From<Bytes> for Body {
#[inline]
fn from(bytes: Bytes) -> Body {
Body {
inner: Inner::Single(Single::Bytes(bytes)),
}
}
}

impl From<Vec<u8>> for Body {
#[inline]
fn from(vec: Vec<u8>) -> Body {
Body {
inner: Inner::Single(Single::Bytes(vec.into())),
}
}
}

impl From<&'static [u8]> for Body {
#[inline]
fn from(s: &'static [u8]) -> Body {
Body {
inner: Inner::Single(Single::Bytes(Bytes::from_static(s))),
}
}
}

impl From<String> for Body {
#[inline]
fn from(s: String) -> Body {
Body {
inner: Inner::Single(Single::Text(s.into())),
}
}
}

impl From<&'static str> for Body {
#[inline]
fn from(s: &'static str) -> Body {
Body {
inner: Inner::Single(Single::Text(s.into())),
}
}
}

impl fmt::Debug for Body {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_struct("Body").finish()
}
}
Loading

0 comments on commit 2cad7e9

Please sign in to comment.