From 845c02cb86f3ce5ff210a530855d86e1b5471c60 Mon Sep 17 00:00:00 2001 From: fakeshadow <24548779@qq.com> Date: Thu, 15 Apr 2021 16:54:51 -0700 Subject: [PATCH] Add responder impl for Cow (#2164) --- actix-http/src/body/body.rs | 16 ++++++- src/responder.rs | 85 +++++++++++++++++++------------------ 2 files changed, 57 insertions(+), 44 deletions(-) diff --git a/actix-http/src/body/body.rs b/actix-http/src/body/body.rs index 5fc461d41..4fe18338a 100644 --- a/actix-http/src/body/body.rs +++ b/actix-http/src/body/body.rs @@ -1,4 +1,5 @@ use std::{ + borrow::Cow, fmt, mem, pin::Pin, task::{Context, Poll}, @@ -118,12 +119,23 @@ impl From for Body { } } -impl<'a> From<&'a String> for Body { - fn from(s: &'a String) -> Body { +impl From<&'_ String> for Body { + fn from(s: &String) -> Body { Body::Bytes(Bytes::copy_from_slice(AsRef::<[u8]>::as_ref(&s))) } } +impl From> for Body { + fn from(s: Cow<'_, str>) -> Body { + match s { + Cow::Owned(s) => Body::from(s), + Cow::Borrowed(s) => { + Body::Bytes(Bytes::copy_from_slice(AsRef::<[u8]>::as_ref(s))) + } + } + } +} + impl From for Body { fn from(s: Bytes) -> Body { Body::Bytes(s) diff --git a/src/responder.rs b/src/responder.rs index 2348e9276..7b8288ed8 100644 --- a/src/responder.rs +++ b/src/responder.rs @@ -1,4 +1,4 @@ -use std::fmt; +use std::{borrow::Cow, fmt}; use actix_http::{ body::Body, @@ -117,53 +117,29 @@ impl Responder for (T, StatusCode) { } } -impl Responder for &'static str { - fn respond_to(self, _: &HttpRequest) -> HttpResponse { - HttpResponse::Ok() - .content_type(mime::TEXT_PLAIN_UTF_8) - .body(self) - } +macro_rules! impl_responder { + ($res: ty, $ct: path) => { + impl Responder for $res { + fn respond_to(self, _: &HttpRequest) -> HttpResponse { + HttpResponse::Ok().content_type($ct).body(self) + } + } + }; } -impl Responder for &'static [u8] { - fn respond_to(self, _: &HttpRequest) -> HttpResponse { - HttpResponse::Ok() - .content_type(mime::APPLICATION_OCTET_STREAM) - .body(self) - } -} +impl_responder!(&'static str, mime::TEXT_PLAIN_UTF_8); -impl Responder for String { - fn respond_to(self, _: &HttpRequest) -> HttpResponse { - HttpResponse::Ok() - .content_type(mime::TEXT_PLAIN_UTF_8) - .body(self) - } -} +impl_responder!(String, mime::TEXT_PLAIN_UTF_8); -impl<'a> Responder for &'a String { - fn respond_to(self, _: &HttpRequest) -> HttpResponse { - HttpResponse::Ok() - .content_type(mime::TEXT_PLAIN_UTF_8) - .body(self) - } -} +impl_responder!(&'_ String, mime::TEXT_PLAIN_UTF_8); -impl Responder for Bytes { - fn respond_to(self, _: &HttpRequest) -> HttpResponse { - HttpResponse::Ok() - .content_type(mime::APPLICATION_OCTET_STREAM) - .body(self) - } -} +impl_responder!(Cow<'_, str>, mime::TEXT_PLAIN_UTF_8); -impl Responder for BytesMut { - fn respond_to(self, _: &HttpRequest) -> HttpResponse { - HttpResponse::Ok() - .content_type(mime::APPLICATION_OCTET_STREAM) - .body(self) - } -} +impl_responder!(&'static [u8], mime::APPLICATION_OCTET_STREAM); + +impl_responder!(Bytes, mime::APPLICATION_OCTET_STREAM); + +impl_responder!(BytesMut, mime::APPLICATION_OCTET_STREAM); /// Allows overriding status code and headers for a responder. pub struct CustomResponder { @@ -358,6 +334,31 @@ pub(crate) mod tests { HeaderValue::from_static("text/plain; charset=utf-8") ); + let s = String::from("test"); + let resp = Cow::Borrowed(s.as_str()).respond_to(&req); + assert_eq!(resp.status(), StatusCode::OK); + assert_eq!(resp.body().bin_ref(), b"test"); + assert_eq!( + resp.headers().get(CONTENT_TYPE).unwrap(), + HeaderValue::from_static("text/plain; charset=utf-8") + ); + + let resp = Cow::<'_, str>::Owned(s).respond_to(&req); + assert_eq!(resp.status(), StatusCode::OK); + assert_eq!(resp.body().bin_ref(), b"test"); + assert_eq!( + resp.headers().get(CONTENT_TYPE).unwrap(), + HeaderValue::from_static("text/plain; charset=utf-8") + ); + + let resp = Cow::Borrowed("test").respond_to(&req); + assert_eq!(resp.status(), StatusCode::OK); + assert_eq!(resp.body().bin_ref(), b"test"); + assert_eq!( + resp.headers().get(CONTENT_TYPE).unwrap(), + HeaderValue::from_static("text/plain; charset=utf-8") + ); + let resp = Bytes::from_static(b"test").respond_to(&req); assert_eq!(resp.status(), StatusCode::OK); assert_eq!(resp.body().bin_ref(), b"test");