use crate::{
Codec, Encoding, Prost, server::streaming::RequestStream, timeout::parse_grpc_timeout,
};
use std::{marker::PhantomData, time::Instant};
use trillium::{Conn, Headers};
pub struct GrpcServerConn<C = Prost> {
conn: Conn,
response_trailers: Headers,
request_encoding: Encoding,
deadline: Option<Instant>,
codec: PhantomData<fn() -> C>,
}
impl<C> GrpcServerConn<C> {
pub(crate) fn new(conn: Conn, request_encoding: Encoding) -> Self {
let deadline = conn
.request_headers()
.get_str("grpc-timeout")
.and_then(parse_grpc_timeout)
.map(|d| Instant::now() + d);
Self {
conn,
response_trailers: Headers::new(),
request_encoding,
deadline,
codec: PhantomData,
}
}
pub fn received_headers(&self) -> &Headers {
self.conn.request_headers()
}
pub fn response_headers_mut(&mut self) -> &mut Headers {
self.conn.response_headers_mut()
}
pub fn response_trailers_mut(&mut self) -> &mut Headers {
&mut self.response_trailers
}
pub fn deadline(&self) -> Option<Instant> {
self.deadline
}
pub fn requests<Req>(&mut self) -> RequestStream<'_, Req>
where
C: Codec<Req>,
Req: 'static,
{
RequestStream::new(
Box::pin(self.conn.request_body()),
<C as Codec<Req>>::decode,
self.request_encoding,
)
}
pub(crate) fn into_parts(self) -> (Conn, Headers) {
(self.conn, self.response_trailers)
}
}