use std::sync::Arc; use futures::{Sink, Stream}; use tokio::sync::Mutex; use super::{IntoTransport, Transport}; use crate::service::{RxJsonRpcMessage, ServiceRole, TxJsonRpcMessage}; pub struct SinkStreamTransport { stream: St, sink: Arc>, } impl SinkStreamTransport { pub fn new(sink: Si, stream: St) -> Self { Self { stream, sink: Arc::new(Mutex::new(sink)), } } } impl Transport for SinkStreamTransport where St: Send + Stream> + Unpin, Si: Send + Sink> + Unpin + 'static, { type Error = Si::Error; fn send( &mut self, item: TxJsonRpcMessage, ) -> impl Future> + Send + 'static { use futures::SinkExt; let lock = self.sink.clone(); async move { let mut write = lock.lock().await; write.send(item).await } } fn receive(&mut self) -> impl Future>> { use futures::StreamExt; self.stream.next() } async fn close(&mut self) -> Result<(), Self::Error> { Ok(()) } } pub enum TransportAdapterSinkStream {} impl IntoTransport for (Si, St) where Role: ServiceRole, Si: Send + Sink> + Unpin + 'static, St: Send + Stream> + Unpin + 'static, Si::Error: std::error::Error + Send + 'static, { fn into_transport(self) -> impl Transport + 'static { SinkStreamTransport::new(self.0, self.1) } } pub enum TransportAdapterAsyncCombinedRW {} impl IntoTransport for S where Role: ServiceRole, S: Sink> + Stream> + Send + 'static, S::Error: std::error::Error + Send + 'static, { fn into_transport(self) -> impl Transport + 'static { use futures::StreamExt; IntoTransport::::into_transport(self.split()) } }