use std::fmt::Display;
use std::time::Instant;
use tonic::async_trait;
use crate::core::RecvMessage;
use crate::core::RequestHeaders;
use crate::core::ResponseHeaders;
use crate::core::SendMessage;
use crate::core::Trailers;
mod channel;
pub mod interceptor;
pub mod metadata_utils;
pub(crate) mod service_config;
pub mod stream_util;
pub use channel::Channel;
pub use channel::ChannelOptions;
pub(crate) mod load_balancing;
pub(crate) mod name_resolution;
mod subchannel;
pub(crate) mod transport;
#[cfg(test)]
mod test_util;
#[derive(Copy, Clone, PartialEq, Eq, Debug, Default)]
pub enum ConnectivityState {
#[default]
Idle,
Connecting,
Ready,
TransientFailure,
}
impl Display for ConnectivityState {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
ConnectivityState::Idle => write!(f, "Idle"),
ConnectivityState::Connecting => write!(f, "Connecting"),
ConnectivityState::Ready => write!(f, "Ready"),
ConnectivityState::TransientFailure => write!(f, "TransientFailure"),
}
}
}
#[derive(Default, Clone)]
#[non_exhaustive]
pub struct CallOptions {
deadline: Option<Instant>,
}
impl CallOptions {
pub fn new() -> Self {
Self::default()
}
pub fn set_deadline(&mut self, deadline: Instant) {
self.deadline = Some(deadline);
}
pub fn deadline(&self) -> Option<Instant> {
self.deadline
}
}
#[trait_variant::make(Send)]
pub trait Invoke: Sync {
type SendStream: SendStream + 'static;
type RecvStream: RecvStream + 'static;
async fn invoke(
&self,
headers: RequestHeaders,
options: CallOptions,
) -> (Self::SendStream, Self::RecvStream);
}
#[async_trait]
pub trait DynInvoke: Send + Sync {
async fn dyn_invoke(
&self,
headers: RequestHeaders,
options: CallOptions,
) -> (Box<dyn DynSendStream>, Box<dyn DynRecvStream>);
}
#[async_trait]
impl<T: Invoke> DynInvoke for T {
async fn dyn_invoke(
&self,
headers: RequestHeaders,
options: CallOptions,
) -> (Box<dyn DynSendStream>, Box<dyn DynRecvStream>) {
let (tx, rx) = self.invoke(headers, options).await;
(Box::new(tx), Box::new(rx))
}
}
#[trait_variant::make(Send)]
pub trait InvokeOnce: Sync {
type SendStream: SendStream + 'static;
type RecvStream: RecvStream + 'static;
async fn invoke_once(
self,
headers: RequestHeaders,
options: CallOptions,
) -> (Self::SendStream, Self::RecvStream);
}
impl<T: Invoke> InvokeOnce for &T {
type SendStream = T::SendStream;
type RecvStream = T::RecvStream;
async fn invoke_once(
self,
headers: RequestHeaders,
options: CallOptions,
) -> (Self::SendStream, Self::RecvStream) {
self.invoke(headers, options).await
}
}
#[trait_variant::make(Send)]
pub trait SendStream {
async fn send(&mut self, msg: &dyn SendMessage, options: SendOptions) -> Result<(), ()>;
}
#[async_trait]
pub trait DynSendStream: Send {
async fn dyn_send(&mut self, msg: &dyn SendMessage, options: SendOptions) -> Result<(), ()>;
}
#[async_trait]
impl<T: SendStream> DynSendStream for T {
async fn dyn_send(&mut self, msg: &dyn SendMessage, options: SendOptions) -> Result<(), ()> {
self.send(msg, options).await
}
}
impl<'a> SendStream for Box<dyn DynSendStream + 'a> {
async fn send(&mut self, msg: &dyn SendMessage, options: SendOptions) -> Result<(), ()> {
(**self).dyn_send(msg, options).await
}
}
#[derive(Default, Clone)]
#[non_exhaustive]
pub struct SendOptions {
pub final_msg: bool,
pub disable_compression: bool,
}
impl SendOptions {
pub fn new() -> Self {
Self::default()
}
pub fn with_final_msg(mut self, final_msg: bool) -> Self {
self.final_msg = final_msg;
self
}
pub fn with_disable_compression(mut self, disable_compression: bool) -> Self {
self.disable_compression = disable_compression;
self
}
}
#[derive(Debug, Clone)]
pub enum ResponseStreamItem {
Headers(ResponseHeaders),
Message,
Trailers(Trailers),
StreamClosed,
}
#[trait_variant::make(Send)]
pub trait RecvStream {
async fn recv(&mut self, msg: &mut dyn RecvMessage) -> ResponseStreamItem;
}
#[async_trait]
pub trait DynRecvStream: Send {
async fn dyn_recv(&mut self, msg: &mut dyn RecvMessage) -> ResponseStreamItem;
}
#[async_trait]
impl<T: RecvStream> DynRecvStream for T {
async fn dyn_recv(&mut self, msg: &mut dyn RecvMessage) -> ResponseStreamItem {
self.recv(msg).await
}
}
impl<'a> RecvStream for Box<dyn DynRecvStream + 'a> {
async fn recv(&mut self, msg: &mut dyn RecvMessage) -> ResponseStreamItem {
(**self).dyn_recv(msg).await
}
}