mirror of https://github.com/fafhrd91/actix-net
124 lines
3.0 KiB
Rust
124 lines
3.0 KiB
Rust
use std::marker::PhantomData;
|
|
use std::pin::Pin;
|
|
use std::task::{Context, Poll};
|
|
|
|
use actix_codec::{AsyncRead, AsyncWrite, Decoder, Encoder, Framed};
|
|
use actix_utils::mpsc::Receiver;
|
|
use futures::Stream;
|
|
|
|
pub struct Connect<Io, Codec>
|
|
where
|
|
Codec: Encoder + Decoder,
|
|
{
|
|
io: Io,
|
|
_t: PhantomData<Codec>,
|
|
}
|
|
|
|
impl<Io, Codec> Connect<Io, Codec>
|
|
where
|
|
Io: AsyncRead + AsyncWrite,
|
|
Codec: Encoder + Decoder,
|
|
{
|
|
pub(crate) fn new(io: Io) -> Self {
|
|
Self {
|
|
io,
|
|
_t: PhantomData,
|
|
}
|
|
}
|
|
|
|
pub fn codec(
|
|
self,
|
|
codec: Codec,
|
|
) -> ConnectResult<Io, (), Codec, Receiver<<Codec as Encoder>::Item>> {
|
|
ConnectResult {
|
|
state: (),
|
|
out: None,
|
|
framed: Framed::new(self.io, codec),
|
|
}
|
|
}
|
|
}
|
|
|
|
#[pin_project::pin_project]
|
|
pub struct ConnectResult<Io, St, Codec: Encoder + Decoder, Out> {
|
|
pub(crate) state: St,
|
|
pub(crate) out: Option<Out>,
|
|
#[pin]
|
|
pub(crate) framed: Framed<Io, Codec>,
|
|
}
|
|
|
|
impl<Io, St, Codec: Encoder + Decoder, Out: Unpin> ConnectResult<Io, St, Codec, Out> {
|
|
#[inline]
|
|
pub fn get_ref(&self) -> &Io {
|
|
self.framed.get_ref()
|
|
}
|
|
|
|
#[inline]
|
|
pub fn get_mut(&mut self) -> &mut Io {
|
|
self.framed.get_mut()
|
|
}
|
|
|
|
pub fn out<U>(self, out: U) -> ConnectResult<Io, St, Codec, U>
|
|
where
|
|
U: Stream<Item = <Codec as Encoder>::Item> + Unpin,
|
|
{
|
|
ConnectResult {
|
|
state: self.state,
|
|
framed: self.framed,
|
|
out: Some(out),
|
|
}
|
|
}
|
|
|
|
#[inline]
|
|
pub fn state<S>(self, state: S) -> ConnectResult<Io, S, Codec, Out> {
|
|
ConnectResult {
|
|
state,
|
|
framed: self.framed,
|
|
out: self.out,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl<Io, St, Codec, Out> Stream for ConnectResult<Io, St, Codec, Out>
|
|
where
|
|
Io: AsyncRead + AsyncWrite,
|
|
Codec: Encoder + Decoder,
|
|
{
|
|
type Item = Result<<Codec as Decoder>::Item, <Codec as Decoder>::Error>;
|
|
|
|
fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
|
|
self.project().framed.next_item(cx)
|
|
}
|
|
}
|
|
|
|
impl<Io, St, Codec, Out> futures::Sink<<Codec as Encoder>::Item>
|
|
for ConnectResult<Io, St, Codec, Out>
|
|
where
|
|
Io: AsyncRead + AsyncWrite,
|
|
Codec: Encoder + Decoder,
|
|
{
|
|
type Error = <Codec as Encoder>::Error;
|
|
|
|
fn poll_ready(mut self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
|
if self.as_mut().project().framed.is_write_ready() {
|
|
Poll::Ready(Ok(()))
|
|
} else {
|
|
Poll::Pending
|
|
}
|
|
}
|
|
|
|
fn start_send(
|
|
self: Pin<&mut Self>,
|
|
item: <Codec as Encoder>::Item,
|
|
) -> Result<(), Self::Error> {
|
|
self.project().framed.write(item)
|
|
}
|
|
|
|
fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
|
self.as_mut().project().framed.flush(cx)
|
|
}
|
|
|
|
fn poll_close(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
|
self.as_mut().project().framed.close(cx)
|
|
}
|
|
}
|