use h3::error::Code;
use hyper::body::Buf;
pub(crate) trait StopSendStream {
fn stop_send_stream(&mut self, code: Code);
}
impl<S, B> StopSendStream for h3::client::RequestStream<S, B>
where
S: h3::quic::SendStream<B>,
B: Buf,
{
fn stop_send_stream(&mut self, code: Code) {
self.stop_stream(code);
}
}
impl<S, B> StopSendStream for h3::server::RequestStream<S, B>
where
S: h3::quic::SendStream<B>,
B: Buf,
{
fn stop_send_stream(&mut self, code: Code) {
self.stop_stream(code);
}
}
impl<T: StopSendStream> StopSendStream for &mut T {
fn stop_send_stream(&mut self, code: Code) {
(**self).stop_send_stream(code);
}
}
pub(crate) struct SendResetGuard<W: StopSendStream> {
w: W,
armed: bool,
code: Code,
}
impl<W: StopSendStream> SendResetGuard<W> {
pub(crate) fn new(w: W) -> Self {
Self {
w,
armed: true,
code: Code::H3_REQUEST_CANCELLED,
}
}
pub(crate) fn disarm(&mut self) {
self.armed = false;
}
pub(crate) fn set_error_code(&mut self, code: Code) {
self.code = code;
}
}
impl<W: StopSendStream> std::ops::Deref for SendResetGuard<W> {
type Target = W;
fn deref(&self) -> &Self::Target {
&self.w
}
}
impl<W: StopSendStream> std::ops::DerefMut for SendResetGuard<W> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.w
}
}
impl<W: StopSendStream> Drop for SendResetGuard<W> {
fn drop(&mut self) {
if self.armed {
self.w.stop_send_stream(self.code);
}
}
}