iscp-rs 1.1.2

iSCPv2 Client Library
Documentation
//! トランスポート

mod compression;
mod negotiation;
pub mod quic;
pub mod websocket;

#[cfg(feature = "unstable-webtransport")]
#[cfg_attr(docsrs, doc(cfg(feature = "unstable-webtransport")))]
pub mod webtransport;

mod datagram;
mod tls;

pub use compression::*;
pub use negotiation::*;
pub use tls::Certificate;

/// トランスポートのエラー
pub struct TransportError {
    inner: Box<dyn std::error::Error + Send + Sync>,
}

impl std::fmt::Debug for TransportError {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        f.debug_tuple("TransportError").field(&self.inner).finish()
    }
}

impl std::fmt::Display for TransportError {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "transport error: {}", self.inner)
    }
}

impl std::error::Error for TransportError {}

#[derive(Debug, thiserror::Error)]
#[error("{0}")]
struct TransportErrorMessage(String);

impl TransportError {
    pub fn new<E: std::error::Error + Send + Sync + 'static>(err: E) -> Self {
        Self {
            inner: Box::new(err),
        }
    }

    pub fn from_msg<T: std::fmt::Display>(msg: T) -> Self {
        Self {
            inner: Box::new(TransportErrorMessage(msg.to_string())),
        }
    }
}

pub trait TransportWriter: Send {
    fn write(
        &mut self,
        data: &[u8],
    ) -> impl std::future::Future<Output = Result<(), TransportError>> + Send;

    fn close(&mut self) -> impl std::future::Future<Output = Result<(), TransportError>> + Send;
}

pub trait TransportReader: Send {
    fn read(
        &mut self,
        buf: &mut bytes::BytesMut,
    ) -> impl std::future::Future<Output = Result<(), TransportError>> + Send;

    fn close(&mut self) -> impl std::future::Future<Output = Result<(), TransportError>> + Send;
}

pub trait TransportCloser: Send {
    fn close(&mut self) -> impl std::future::Future<Output = Result<(), TransportError>> + Send;
}

/// トランスポート
pub struct Transport<C: Connector> {
    pub reader: C::Reader,
    pub writer: C::Writer,
    pub closer: C::Closer,
    pub unreliable_reader: Option<C::UnreliableReader>,
    pub unreliable_writer: Option<C::UnreliableWriter>,
}

pub trait Connector: Send + Sized + 'static {
    type Reader: TransportReader + 'static;
    type Writer: TransportWriter + 'static;
    type Closer: TransportCloser + 'static;
    type UnreliableReader: TransportReader + 'static;
    type UnreliableWriter: TransportWriter + 'static;

    fn connect(
        &self,
        negotiation_params: NegotiationParams,
    ) -> impl std::future::Future<Output = Result<Transport<Self>, TransportError>> + Send;

    #[doc(hidden)]
    fn _compat_with_context_takeover() -> bool {
        false
    }
}

#[derive(Clone, Copy, Debug)]
pub enum UnreliableNotSupported {}

impl TransportReader for UnreliableNotSupported {
    async fn read(&mut self, _buf: &mut bytes::BytesMut) -> Result<(), TransportError> {
        unreachable!()
    }

    async fn close(&mut self) -> Result<(), TransportError> {
        unreachable!()
    }
}

impl TransportWriter for UnreliableNotSupported {
    async fn write(&mut self, _data: &[u8]) -> Result<(), TransportError> {
        unreachable!()
    }

    async fn close(&mut self) -> Result<(), TransportError> {
        unreachable!()
    }
}