From c8cd130770493e292ea3e06410666a7cca79320c Mon Sep 17 00:00:00 2001 From: Frank Steffahn Date: Sun, 25 Oct 2020 21:51:04 +0100 Subject: [PATCH 1/2] Make Request::send more general. Removes `+ 'static` constraint from the `impl Read` parameter. For this, lifetime parameters are added to `Payload` and `SizedReader`. --- src/body.rs | 24 ++++++++++++------------ src/request.rs | 2 +- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/body.rs b/src/body.rs index 1a99792..474977d 100644 --- a/src/body.rs +++ b/src/body.rs @@ -15,16 +15,16 @@ use super::SerdeValue; /// The different kinds of bodies to send. /// /// *Internal API* -pub(crate) enum Payload { +pub(crate) enum Payload<'a> { Empty, Text(String, String), #[cfg(feature = "json")] JSON(SerdeValue), - Reader(Box), + Reader(Box), Bytes(Vec), } -impl fmt::Debug for Payload { +impl fmt::Debug for Payload<'_> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { Payload::Empty => write!(f, "Empty"), @@ -37,8 +37,8 @@ impl fmt::Debug for Payload { } } -impl Default for Payload { - fn default() -> Payload { +impl Default for Payload<'_> { + fn default() -> Self { Payload::Empty } } @@ -56,25 +56,25 @@ pub(crate) enum BodySize { /// Payloads are turned into this type where we can hold both a size and the reader. /// /// *Internal API* -pub(crate) struct SizedReader { +pub(crate) struct SizedReader<'a> { pub size: BodySize, - pub reader: Box, + pub reader: Box, } -impl fmt::Debug for SizedReader { +impl fmt::Debug for SizedReader<'_> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "SizedReader[size={:?},reader]", self.size) } } -impl SizedReader { - fn new(size: BodySize, reader: Box) -> Self { +impl<'a> SizedReader<'a> { + fn new(size: BodySize, reader: Box) -> Self { SizedReader { size, reader } } } -impl Payload { - pub fn into_read(self) -> SizedReader { +impl<'a> Payload<'a> { + pub fn into_read(self) -> SizedReader<'a> { match self { Payload::Empty => SizedReader::new(BodySize::Empty, Box::new(empty())), Payload::Text(text, _charset) => { diff --git a/src/request.rs b/src/request.rs index 7d469fb..152687e 100644 --- a/src/request.rs +++ b/src/request.rs @@ -227,7 +227,7 @@ impl Request { /// .set("Content-Type", "text/plain") /// .send(read); /// ``` - pub fn send(&mut self, reader: impl Read + 'static) -> Response { + pub fn send(&mut self, reader: impl Read) -> Response { self.do_call(Payload::Reader(Box::new(reader))) } From 17ab5110a34ccc8add0bd6a1cfd7f137187c8da9 Mon Sep 17 00:00:00 2001 From: Jacob Hoffman-Andrews Date: Sun, 25 Oct 2020 15:52:02 -0700 Subject: [PATCH 2/2] Use lifetimes for more elements of Payload Text and Bytes can both have their lifetimes parameterized. --- src/body.rs | 6 +++--- src/request.rs | 13 +++++++++---- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/src/body.rs b/src/body.rs index 474977d..8a48d32 100644 --- a/src/body.rs +++ b/src/body.rs @@ -17,11 +17,11 @@ use super::SerdeValue; /// *Internal API* pub(crate) enum Payload<'a> { Empty, - Text(String, String), + Text(&'a str, String), #[cfg(feature = "json")] JSON(SerdeValue), Reader(Box), - Bytes(Vec), + Bytes(&'a [u8]), } impl fmt::Debug for Payload<'_> { @@ -86,7 +86,7 @@ impl<'a> Payload<'a> { encoding.encode(&text, EncoderTrap::Replace).unwrap() }; #[cfg(not(feature = "charset"))] - let bytes = text.into_bytes(); + let bytes = text.as_bytes(); let len = bytes.len(); let cursor = Cursor::new(bytes); SizedReader::new(BodySize::Known(len as u64), Box::new(cursor)) diff --git a/src/request.rs b/src/request.rs index 152687e..a8976ae 100644 --- a/src/request.rs +++ b/src/request.rs @@ -153,7 +153,7 @@ impl Request { /// println!("{:?}", r); /// ``` pub fn send_bytes(&mut self, data: &[u8]) -> Response { - self.do_call(Payload::Bytes(data.to_owned())) + self.do_call(Payload::Bytes(data)) } /// Send data as a string. @@ -178,10 +178,9 @@ impl Request { /// println!("{:?}", r); /// ``` pub fn send_string(&mut self, data: &str) -> Response { - let text = data.into(); let charset = crate::response::charset_from_content_type(self.header("content-type")).to_string(); - self.do_call(Payload::Text(text, charset)) + self.do_call(Payload::Text(data, charset)) } /// Send a sequence of (key, value) pairs as form-urlencoded data. @@ -206,7 +205,7 @@ impl Request { let encoded = form_urlencoded::Serializer::new(String::new()) .extend_pairs(data) .finish(); - self.do_call(Payload::Bytes(encoded.into_bytes())) + self.do_call(Payload::Bytes(&encoded.into_bytes())) } /// Send data from a reader. @@ -668,3 +667,9 @@ fn no_hostname() { ); assert!(req.get_host().is_err()); } + +#[test] +fn send_byte_slice() { + let bytes = vec![1, 2, 3]; + crate::agent().post("http://example.com").send(&bytes[1..2]); +}