#![cfg_attr(feature = "mockable", expect(unused_lifetimes, reason = "codegen"))]
use async_trait::async_trait;
use derive_more::with_trait::Display;
use futures::stream::LocalBoxStream;
use medea_client_api_proto::{ClientMsg, ServerMsg};
use tracerr::Traced;
use crate::{
platform,
rpc::{ApiUrl, ClientDisconnect, CloseMsg},
utils::{Caused, JsonParseError},
};
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum TransportState {
Connecting,
Open,
Closing,
Closed(CloseMsg),
}
impl TransportState {
#[must_use]
pub const fn can_close(self) -> bool {
matches!(self, Self::Connecting | Self::Open)
}
}
#[async_trait(?Send)]
#[cfg_attr(feature = "mockable", mockall::automock)]
pub trait RpcTransport {
async fn connect(&self, url: ApiUrl) -> Result<(), Traced<TransportError>>;
fn on_message(&self) -> LocalBoxStream<'static, ServerMsg>;
fn set_close_reason(&self, reason: ClientDisconnect);
fn send(&self, msg: &ClientMsg) -> Result<(), Traced<TransportError>>;
fn on_state_change(&self) -> LocalBoxStream<'static, TransportState>;
}
#[derive(Caused, Clone, Debug, Display, PartialEq)]
#[cause(error = platform::Error)]
pub enum TransportError {
#[display("Failed to create WebSocket: {_0}")]
CreateSocket(platform::Error),
#[display("Failed to init WebSocket")]
InitSocket,
#[display("Failed to parse client message: {_0}")]
SerializeClientMessage(JsonParseError),
#[display("Failed to parse server message: {_0}")]
ParseServerMessage(JsonParseError),
#[display("Message is not a string")]
MessageNotString,
#[display("Failed to send message: {_0}")]
SendMessage(platform::Error),
#[display("Underlying socket is closed")]
ClosedSocket,
}