Skip to content

Instantly share code, notes, and snippets.

@KodrAus
Last active March 16, 2017 00:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save KodrAus/39be38b72cbd8b45711dcba92019cccf to your computer and use it in GitHub Desktop.
Save KodrAus/39be38b72cbd8b45711dcba92019cccf to your computer and use it in GitHub Desktop.
New Request Body
pub struct Url<'a>(&'a str);
pub struct Body<R>(R);
type DefaultBody = &'static [u8];
impl<R> Body<R> {
pub fn new(inner: R) -> Self {
Body(inner)
}
pub fn into_inner(self) -> R {
self.0
}
}
impl Body<DefaultBody> {
pub fn none() -> Self {
Body(&[])
}
}
pub struct SearchRequest<'a, R> {
pub url: Url<'a>,
pub body: Body<R>,
}
impl<'a, R> SearchRequest<'a, R>
where R: 'a
{
pub fn new(body: R) -> Self {
SearchRequest {
url: Url("/"),
body: Body::new(body),
}
}
}
pub struct PingRequest<'a> {
pub url: Url<'a>,
}
impl<'a> PingRequest<'a> {
pub fn new() -> Self {
PingRequest {
url: Url("/"),
}
}
}
pub struct HttpRequest<'a, R> {
pub url: Url<'a>,
pub body: Option<Body<R>>,
}
impl<'a, R> Into<HttpRequest<'a, R>> for SearchRequest<'a, R>
where R: 'a
{
fn into(self) -> HttpRequest<'a, R> {
HttpRequest {
url: self.url,
body: Some(self.body),
}
}
}
impl<'a> Into<HttpRequest<'a, DefaultBody>> for PingRequest<'a> {
fn into(self) -> HttpRequest<'a, &'static [u8]> {
HttpRequest {
url: self.url,
body: None,
}
}
}
trait HyperBody {
fn into_hyper_body(self) -> ();
}
impl <R: AsRef<[u8]>> HyperBody for R {
fn into_hyper_body(self) -> () {}
}
fn request<R: Into<HttpRequest<'static, B>>, B: HyperBody>(_req: R) {
}
fn main() {
request(SearchRequest::new(vec![]));
request(PingRequest::new());
}
@KodrAus
Copy link
Author

KodrAus commented Feb 8, 2017

Might be more useful to turn Cursor<Vec<u8>> into a Cow<'a, [u8]>? Or just leave the type as-is.

The idea for using a Cursor was so it would work with a Read bound. But consumers could implement their own trait for whatever types they want to support and wrap that in a Read if necessary. Seems like a better way to go to avoid making assumptions about how it's used.

This would allow the optimisation of passing already owned types along rather than having to copy them, like getting a Vec.

@KodrAus
Copy link
Author

KodrAus commented Feb 8, 2017

I think it's worth keeping in mind that Body is a mediating type. It sits between your code and the up layer. So you might be using straight Vecs, or pooling and it should all just work. It knows nothing about what the Body is. It's up to the request sender to specify the types it can work with and it's up to the caller to fulfill them.

The From bounds are just for convenience and keeping them all producing the same type is handy.

@KodrAus
Copy link
Author

KodrAus commented Feb 9, 2017

Also check out this thread: hyperium/hyper#953 (comment)

The BoxRef<Mmap> stuff is interesting. As an example we should verify that the new body type will work with alternative ways of handling bytes. (It does thanks to the R parameter, but nice to show it).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment