Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add conversions to and from bytes #100

Merged
merged 1 commit into from Apr 24, 2020
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
@@ -1,3 +1,4 @@
use async_std::io::prelude::*;
use async_std::io::{self, BufRead, Read};

use std::fmt::{self, Debug};
@@ -81,7 +82,7 @@ impl Body {

/// Create a `Body` from a reader with an optional length.
///
/// The Mime type set to `application/octet-stream` if no other mime type has been set or can
/// The Mime type is set to `application/octet-stream` if no other mime type has been set or can
/// be sniffed. If a `Body` has no length, HTTP implementations will often switch over to
/// framed messages such as [Chunked
/// Encoding](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Transfer-Encoding).
@@ -109,6 +110,53 @@ impl Body {
}
}

/// Create a `Body` from a Vec of bytes.
///
/// The Mime type is set to `application/octet-stream` if no other mime type has been set or can
/// be sniffed. If a `Body` has no length, HTTP implementations will often switch over to
/// framed messages such as [Chunked
/// Encoding](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Transfer-Encoding).
///
/// # Examples
///
/// ```
/// use http_types::{Body, Response, StatusCode};
/// use async_std::io::Cursor;
///
/// let mut req = Response::new(StatusCode::Ok);
///
/// let input = vec![1, 2, 3];
/// req.set_body(Body::from_bytes(input));
/// ```
pub fn from_bytes(bytes: Vec<u8>) -> Self {
Self {
mime: mime::BYTE_STREAM,
length: Some(bytes.len()),
reader: Box::new(io::Cursor::new(bytes)),
}
}

/// Parse the body into a `Vec<u8>`.
///
/// # Examples
///
/// ```
/// # fn main() -> Result<(), http_types::Error> { async_std::task::block_on(async {
/// use http_types::Body;
///
/// let bytes = vec![1, 2, 3];
/// let body = Body::from_bytes(bytes);
///
/// let bytes: Vec<u8> = body.into_bytes().await?;
/// assert_eq!(bytes, vec![1, 2, 3]);
/// # Ok(()) }) }
/// ```
pub async fn into_bytes(mut self) -> crate::Result<Vec<u8>> {
let mut buf = Vec::with_capacity(1024);
self.read_to_end(&mut buf).await?;
Ok(buf)
}

/// Get the length of the body in bytes.
///
/// # Examples
@@ -165,7 +213,6 @@ impl Body {
/// # Ok(()) }) }
/// ```
pub async fn into_string(mut self) -> io::Result<String> {
use async_std::io::ReadExt;
let mut result = String::with_capacity(self.len().unwrap_or(0));
self.read_to_string(&mut result).await?;
Ok(result)
@@ -226,6 +226,31 @@ impl Request {
self.body.into_string().await
}

/// Read the body as bytes.
///
/// This consumes the `Request`. If you want to read the body without
/// consuming the request, consider using the `take_body` method and
/// then calling `Body::into_bytes` or using the Request's AsyncRead
/// implementation to read the body.
///
/// # Examples
///
/// ```
/// # fn main() -> Result<(), http_types::Error> { async_std::task::block_on(async {
/// use http_types::{Body, Url, Method, Request};
///
/// let bytes = vec![1, 2, 3];
/// let mut req = Request::new(Method::Get, Url::parse("https://example.com").unwrap());
/// req.set_body(Body::from_bytes(bytes));
///
/// let bytes = req.body_bytes().await?;
/// assert_eq!(bytes, vec![1, 2, 3]);
/// # Ok(()) }) }
/// ```
pub async fn body_bytes(self) -> crate::Result<Vec<u8>> {
self.body.into_bytes().await
}

/// Get an HTTP header.
pub fn header(&self, name: &HeaderName) -> Option<&Vec<HeaderValue>> {
self.headers.get(name)
@@ -254,6 +254,32 @@ impl Response {
self.body.into_string().await
}

/// Read the body as bytes.
///
/// This consumes the `Response`. If you want to read the body without
/// consuming the response, consider using the `take_body` method and
/// then calling `Body::into_bytes` or using the Response's AsyncRead
/// implementation to read the body.
///
/// # Examples
///
/// ```
/// # fn main() -> Result<(), http_types::Error> { async_std::task::block_on(async {
///
/// use http_types::{Body, Url, Method, Response, StatusCode};
///
/// let bytes = vec![1, 2, 3];
/// let mut res = Response::new(StatusCode::Ok);
/// res.set_body(Body::from_bytes(bytes));
///
/// let bytes = res.body_bytes().await?;
/// assert_eq!(bytes, vec![1, 2, 3]);
/// # Ok(()) }) }
/// ```
pub async fn body_bytes(self) -> crate::Result<Vec<u8>> {
self.body.into_bytes().await
}

/// Set the response MIME.
pub fn set_content_type(&mut self, mime: Mime) -> Option<Vec<HeaderValue>> {
let value: HeaderValue = mime.into();