Merge pull request #205 from steffahn/generalize_send_reader_lifetime

Make Request::send more general.
This commit is contained in:
Jacob Hoffman-Andrews
2020-10-25 16:46:13 -07:00
committed by GitHub
2 changed files with 25 additions and 20 deletions

View File

@@ -15,16 +15,16 @@ use super::SerdeValue;
/// The different kinds of bodies to send. /// The different kinds of bodies to send.
/// ///
/// *Internal API* /// *Internal API*
pub(crate) enum Payload { pub(crate) enum Payload<'a> {
Empty, Empty,
Text(String, String), Text(&'a str, String),
#[cfg(feature = "json")] #[cfg(feature = "json")]
JSON(SerdeValue), JSON(SerdeValue),
Reader(Box<dyn Read + 'static>), Reader(Box<dyn Read + 'a>),
Bytes(Vec<u8>), Bytes(&'a [u8]),
} }
impl fmt::Debug for Payload { impl fmt::Debug for Payload<'_> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self { match self {
Payload::Empty => write!(f, "Empty"), Payload::Empty => write!(f, "Empty"),
@@ -37,8 +37,8 @@ impl fmt::Debug for Payload {
} }
} }
impl Default for Payload { impl Default for Payload<'_> {
fn default() -> Payload { fn default() -> Self {
Payload::Empty 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. /// Payloads are turned into this type where we can hold both a size and the reader.
/// ///
/// *Internal API* /// *Internal API*
pub(crate) struct SizedReader { pub(crate) struct SizedReader<'a> {
pub size: BodySize, pub size: BodySize,
pub reader: Box<dyn Read + 'static>, pub reader: Box<dyn Read + 'a>,
} }
impl fmt::Debug for SizedReader { impl fmt::Debug for SizedReader<'_> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "SizedReader[size={:?},reader]", self.size) write!(f, "SizedReader[size={:?},reader]", self.size)
} }
} }
impl SizedReader { impl<'a> SizedReader<'a> {
fn new(size: BodySize, reader: Box<dyn Read + 'static>) -> Self { fn new(size: BodySize, reader: Box<dyn Read + 'a>) -> Self {
SizedReader { size, reader } SizedReader { size, reader }
} }
} }
impl Payload { impl<'a> Payload<'a> {
pub fn into_read(self) -> SizedReader { pub fn into_read(self) -> SizedReader<'a> {
match self { match self {
Payload::Empty => SizedReader::new(BodySize::Empty, Box::new(empty())), Payload::Empty => SizedReader::new(BodySize::Empty, Box::new(empty())),
Payload::Text(text, _charset) => { Payload::Text(text, _charset) => {
@@ -86,7 +86,7 @@ impl Payload {
encoding.encode(&text, EncoderTrap::Replace).unwrap() encoding.encode(&text, EncoderTrap::Replace).unwrap()
}; };
#[cfg(not(feature = "charset"))] #[cfg(not(feature = "charset"))]
let bytes = text.into_bytes(); let bytes = text.as_bytes();
let len = bytes.len(); let len = bytes.len();
let cursor = Cursor::new(bytes); let cursor = Cursor::new(bytes);
SizedReader::new(BodySize::Known(len as u64), Box::new(cursor)) SizedReader::new(BodySize::Known(len as u64), Box::new(cursor))

View File

@@ -153,7 +153,7 @@ impl Request {
/// println!("{:?}", r); /// println!("{:?}", r);
/// ``` /// ```
pub fn send_bytes(&mut self, data: &[u8]) -> Response { 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. /// Send data as a string.
@@ -178,10 +178,9 @@ impl Request {
/// println!("{:?}", r); /// println!("{:?}", r);
/// ``` /// ```
pub fn send_string(&mut self, data: &str) -> Response { pub fn send_string(&mut self, data: &str) -> Response {
let text = data.into();
let charset = let charset =
crate::response::charset_from_content_type(self.header("content-type")).to_string(); 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. /// 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()) let encoded = form_urlencoded::Serializer::new(String::new())
.extend_pairs(data) .extend_pairs(data)
.finish(); .finish();
self.do_call(Payload::Bytes(encoded.into_bytes())) self.do_call(Payload::Bytes(&encoded.into_bytes()))
} }
/// Send data from a reader. /// Send data from a reader.
@@ -227,7 +226,7 @@ impl Request {
/// .set("Content-Type", "text/plain") /// .set("Content-Type", "text/plain")
/// .send(read); /// .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))) self.do_call(Payload::Reader(Box::new(reader)))
} }
@@ -668,3 +667,9 @@ fn no_hostname() {
); );
assert!(req.get_host().is_err()); 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]);
}