Skip to content

Commit c4388fc

Browse files
authored
WASM: Add try_clone implementations to Request and RequestBuilder (#1286)
Currently the wasm client does not implement `try_clone` on `Request` or `RequestBuilder` like the blocking and async clients. This PR adds infallible `try_clone` implementations to the wasm client to improve the API parity. *Note*: Even though these APIs are infallible on wasm (no streaming bodies), I chose to keep the API identical.
1 parent b48cb4a commit c4388fc

File tree

2 files changed

+52
-0
lines changed

2 files changed

+52
-0
lines changed

src/wasm/body.rs

+7
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ pub struct Body {
1717
inner: Inner,
1818
}
1919

20+
#[derive(Clone)]
2021
enum Inner {
2122
Bytes(Bytes),
2223
#[cfg(feature = "multipart")]
@@ -56,6 +57,12 @@ impl Body {
5657
Inner::Multipart(form) => form.is_empty(),
5758
}
5859
}
60+
61+
pub(crate) fn clone(&self) -> Body {
62+
Self {
63+
inner: self.inner.clone(),
64+
}
65+
}
5966
}
6067

6168
impl From<Bytes> for Body {

src/wasm/request.rs

+45
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,21 @@ impl Request {
8989
pub fn body_mut(&mut self) -> &mut Option<Body> {
9090
&mut self.body
9191
}
92+
93+
/// Attempts to clone the `Request`.
94+
///
95+
/// None is returned if a body is which can not be cloned. This method
96+
/// currently always returns `Some`, but that may change in the future.
97+
pub fn try_clone(&self) -> Option<Request> {
98+
Some(Self {
99+
method: self.method.clone(),
100+
url: self.url.clone(),
101+
headers: self.headers.clone(),
102+
body: self.body.as_ref().map(|body| body.clone()),
103+
cors: self.cors,
104+
credentials: self.credentials.clone(),
105+
})
106+
}
92107
}
93108

94109
impl RequestBuilder {
@@ -335,6 +350,36 @@ impl RequestBuilder {
335350
let req = self.request?;
336351
self.client.execute_request(req).await
337352
}
353+
354+
/// Attempt to clone the RequestBuilder.
355+
///
356+
/// `None` is returned if the RequestBuilder can not be cloned. This method
357+
/// currently always returns `Some`, but that may change in the future.
358+
///
359+
/// # Examples
360+
///
361+
/// ```no_run
362+
/// # use reqwest::Error;
363+
/// #
364+
/// # fn run() -> Result<(), Error> {
365+
/// let client = reqwest::Client::new();
366+
/// let builder = client.post("http://httpbin.org/post")
367+
/// .body("from a &str!");
368+
/// let clone = builder.try_clone();
369+
/// assert!(clone.is_some());
370+
/// # Ok(())
371+
/// # }
372+
/// ```
373+
pub fn try_clone(&self) -> Option<RequestBuilder> {
374+
self.request
375+
.as_ref()
376+
.ok()
377+
.and_then(|req| req.try_clone())
378+
.map(|req| RequestBuilder {
379+
client: self.client.clone(),
380+
request: Ok(req),
381+
})
382+
}
338383
}
339384

340385
impl fmt::Debug for Request {

0 commit comments

Comments
 (0)