diff --git a/src/request.rs b/src/request.rs index bfba3b68..1fb23db9 100644 --- a/src/request.rs +++ b/src/request.rs @@ -10,7 +10,7 @@ use crate::headers::{ self, HeaderName, HeaderValue, Headers, Names, ToHeaderValues, Values, CONTENT_TYPE, }; use crate::mime::Mime; -use crate::trailers::{Trailers, TrailersSender}; +use crate::trailers::{self, Trailers}; use crate::Cookie; use crate::{Body, Method, TypeMap, Url, Version}; @@ -31,8 +31,8 @@ pin_project_lite::pin_project! { url: Url, headers: Headers, version: Option, - sender: Option>>, - receiver: sync::Receiver>, + sender: Option>, + receiver: Option>, #[pin] body: Body, local: TypeMap, @@ -50,7 +50,7 @@ impl Request { version: None, body: Body::empty(), sender: Some(sender), - receiver, + receiver: Some(receiver), local: TypeMap::new(), } } @@ -431,17 +431,21 @@ impl Request { } /// Sends trailers to the a receiver. - pub fn send_trailers(&mut self) -> TrailersSender { + pub fn send_trailers(&mut self) -> trailers::Sender { let sender = self .sender .take() .expect("Trailers sender can only be constructed once"); - TrailersSender::new(sender) + trailers::Sender::new(sender) } /// Receive trailers from a sender. - pub async fn recv_trailers(&self) -> Option> { - self.receiver.recv().await + pub async fn recv_trailers(&mut self) -> trailers::Receiver { + let receiver = self + .receiver + .take() + .expect("Trailers receiver can only be constructed once"); + trailers::Receiver::new(receiver) } /// An iterator visiting all header pairs in arbitrary order. diff --git a/src/response.rs b/src/response.rs index c7f4ef14..b87068ca 100644 --- a/src/response.rs +++ b/src/response.rs @@ -10,7 +10,7 @@ use crate::headers::{ self, HeaderName, HeaderValue, Headers, Names, ToHeaderValues, Values, CONTENT_TYPE, }; use crate::mime::Mime; -use crate::trailers::{Trailers, TrailersSender}; +use crate::trailers::{self, Trailers}; use crate::{Body, Cookie, StatusCode, TypeMap, Version}; pin_project_lite::pin_project! { @@ -33,8 +33,8 @@ pin_project_lite::pin_project! { status: StatusCode, headers: Headers, version: Option, - sender: Option>>, - receiver: sync::Receiver>, + sender: Option>, + receiver: Option>, #[pin] body: Body, local: TypeMap, @@ -51,7 +51,7 @@ impl Response { version: None, body: Body::empty(), sender: Some(sender), - receiver, + receiver: Some(receiver), local: TypeMap::new(), } } @@ -396,17 +396,21 @@ impl Response { } /// Sends trailers to the a receiver. - pub fn send_trailers(&mut self) -> TrailersSender { + pub fn send_trailers(&mut self) -> trailers::Sender { let sender = self .sender .take() .expect("Trailers sender can only be constructed once"); - TrailersSender::new(sender) + trailers::Sender::new(sender) } /// Receive trailers from a sender. - pub async fn recv_trailers(&self) -> Option> { - self.receiver.recv().await + pub async fn recv_trailers(&mut self) -> trailers::Receiver { + let receiver = self + .receiver + .take() + .expect("Trailers receiver can only be constructed once"); + trailers::Receiver::new(receiver) } /// An iterator visiting all header pairs in arbitrary order. diff --git a/src/trailers.rs b/src/trailers.rs index bc47b18e..033fbf14 100644 --- a/src/trailers.rs +++ b/src/trailers.rs @@ -34,10 +34,11 @@ //! trailers.insert("Content-Type", "text/plain")?; //! //! task::spawn(async move { -//! let _trailers = req.recv_trailers().await; +//! let trailers = req.recv_trailers().await; +//! # drop(trailers) //! }); //! -//! sender.send(Ok(trailers)).await; +//! sender.send(trailers).await; //! # //! # Ok(()) })} //! ``` @@ -49,10 +50,14 @@ use crate::headers::{ HeaderName, HeaderValue, Headers, Iter, IterMut, Names, ToHeaderValues, Values, }; -use async_std::sync::Sender; +use async_std::prelude::*; +use async_std::sync; use std::convert::TryInto; +use std::future::Future; use std::ops::{Deref, DerefMut}; +use std::pin::Pin; +use std::task::{Context, Poll}; /// A collection of trailing HTTP headers. #[derive(Debug)] @@ -182,21 +187,47 @@ impl DerefMut for Trailers { /// called once, and cannot be cloned. That's because only a single instance of /// `Trailers` should be created. #[derive(Debug)] -pub struct TrailersSender { - sender: Sender>, +pub struct Sender { + sender: sync::Sender, } -impl TrailersSender { - /// Create a new instance of `TrailersSender`. +impl Sender { + /// Create a new instance of `Sender`. #[doc(hidden)] - pub fn new(sender: Sender>) -> Self { + pub fn new(sender: sync::Sender) -> Self { Self { sender } } /// Send a `Trailer`. /// /// The channel will be consumed after having sent trailers. - pub async fn send(self, trailers: crate::Result) { + pub async fn send(self, trailers: Trailers) { self.sender.send(trailers).await } } + +/// The receiving half of a channel to send trailers. +/// +/// Unlike `async_std::sync::channel` the `send` method on this type can only be +/// called once, and cannot be cloned. That's because only a single instance of +/// `Trailers` should be created. +#[must_use = "Futures do nothing unless polled or .awaited"] +#[derive(Debug)] +pub struct Receiver { + receiver: sync::Receiver, +} + +impl Receiver { + /// Create a new instance of `Receiver`. + pub(crate) fn new(receiver: sync::Receiver) -> Self { + Self { receiver } + } +} + +impl Future for Receiver { + type Output = Option; + + fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + Pin::new(&mut self.receiver).poll_next(cx) + } +}