headers icon indicating copy to clipboard operation
headers copied to clipboard

http::Response::Builder interop

Open lnicola opened this issue 6 years ago • 2 comments

An extension trait to offer something like typed_header on http::response::Builder would be nice.

lnicola avatar Jan 28 '19 16:01 lnicola

Yes, I have same issue - how to easily use this crate in creation of hyper::Response with http:response::Builder.

As WA I have now this trait, which adds typed header:

struct HeadersExtender<'a, 'b> {
    builder: &'a mut Builder,
    name: &'b HeaderName

}

impl <'a, 'b> Extend<HeaderValue> for HeadersExtender<'a, 'b> {
    fn extend<I:IntoIterator<Item=HeaderValue>>(&mut self, iter:I) {
        for v in iter.into_iter() {
            self.builder.header(self.name,v);
        }
    }
}

pub trait ResponseBuilderExt {
    fn typed_header<H: Header>(&mut self, header: H) -> &mut Builder;
}

impl ResponseBuilderExt for Builder {
    fn typed_header<H: Header>(&mut self, header: H) -> &mut Builder {
        let mut extender = HeadersExtender{builder:self,name:H::name()};
        header.encode(&mut extender);
        self
    }
}

I hope it's efficient enough, but it would be nice to have it in library already.

izderadicka avatar Apr 04 '19 15:04 izderadicka

Here's my implementation for a typed header trait extension:

use headers::{Header, HeaderMapExt};

pub trait ResponseTypedHeaderExt {
    fn typed_header<H: Header>(self, header: H) -> Self;
}

impl ResponseTypedHeaderExt for hyper::http::response::Builder {
    fn typed_header<H: Header>(mut self, header: H) -> Self {
        self.headers_mut().map(|res| res.typed_insert(header));
        self
    }
}

And an example of it's use:

pub fn redirect_to(uri: Uri) -> http::Response {
    HTTPResponse::builder()
        .status(StatusCode::FOUND)
        .typed_header(Location::from(uri))
        .body(Body::empty())
}

kevinastone avatar Mar 26 '20 15:03 kevinastone