sheave_core::handlers

Trait HandlerConstructor

Source
pub trait HandlerConstructor<RW: AsyncRead + AsyncWrite + Unpin>: AsyncHandler {
    // Required method
    fn new(stream: Arc<RW>) -> Self;
}
Expand description

The interface for providing the way to construct any handler to clients/servers.

Servers / Clients pass streams and contexts to any handler they contain. Here we are necessary to be careful that some stream can’t clone. (e.g. sockets) But we need to share these while handling RTMP communication steps. Therefore this provides the way of cloning stream instances via the (smart) pointer.

§Examples

use std::{
    future::Future,
    io::Result as IOResult,
    marker::PhantomData,
    pin::{
        Pin,
        pin
    },
    sync::Arc,
    task::{
        Context as FutureContext,
        Poll
    }
};
use tokio::io::{
    AsyncRead,
    AsyncWrite,
    ReadBuf
};
use sheave_core::handlers::{
    AsyncHandler,
    HandlerConstructor,
    RtmpContext
};

struct SomethingStream;

impl AsyncRead for SomethingStream {
    fn poll_read(self: Pin<&mut Self>, _cx: &mut FutureContext<'_>, _buf: &mut ReadBuf<'_>) -> Poll<IOResult<()>> {
        // Something to read.

        Poll::Ready(Ok(()))
    }
}

impl AsyncWrite for SomethingStream {
    fn poll_write(self: Pin<&mut Self>, _cx: &mut FutureContext<'_>, buf: &[u8]) -> Poll<IOResult<usize>> {
        // Something to write.

        Poll::Ready(Ok(buf.len()))
    }

    fn poll_flush(self: Pin<&mut Self>, _cx: &mut FutureContext<'_>) -> Poll<IOResult<()>> {
        // Something to flush.

        Poll::Ready(Ok(()))
    }

    fn poll_shutdown(self: Pin<&mut Self>, _cx: &mut FutureContext<'_>) -> Poll<IOResult<()>> {
        // Something to shutdown.

        Poll::Ready(Ok(()))
    }
}

struct SomethingHandler<RW: AsyncRead + AsyncWrite + Unpin>(Arc<RW>);

impl<RW: AsyncRead + AsyncWrite + Unpin> AsyncHandler for SomethingHandler<RW> {
    fn poll_handle(self: Pin<&mut Self>, _cx: &mut FutureContext<'_>, _rtmp_context: &mut RtmpContext) -> Poll<IOResult<()>> {
        // Something to handle.

        Poll::Ready(Ok(()))
    }
}

impl<RW: AsyncRead + AsyncWrite + Unpin> HandlerConstructor<RW> for SomethingHandler<RW> {
    fn new(stream: Arc<RW>) -> Self {
        Self(stream)
    }
}

struct SomethingRunner<RW, C>
where
    RW: AsyncRead + AsyncWrite + Unpin,
    C: HandlerConstructor<RW>
{
    stream: Arc<RW>,
    rtmp_context: Arc<RtmpContext>,
    handler_constructor: PhantomData<C>
}

impl<RW, C> SomethingRunner<RW, C>
where
    RW: AsyncRead + AsyncWrite + Unpin,
    C: HandlerConstructor<RW>
{
    pub fn new(stream: RW, rtmp_context: RtmpContext, handler_constructor: PhantomData<C>) -> Self {
        Self {
            stream: Arc::new(stream),
            rtmp_context: Arc::new(rtmp_context),
            handler_constructor
        }
    }
}

impl<RW, C> Future for SomethingRunner<RW, C>
where
    RW: AsyncRead + AsyncWrite + Unpin,
    C: HandlerConstructor<RW>
{
    type Output = IOResult<()>;

    fn poll(self: Pin<&mut Self>, cx: &mut FutureContext<'_>) -> Poll<Self::Output> {
        pin!(C::new(Arc::clone(&self.stream))).poll_handle(cx, self.rtmp_context.make_weak_mut())
    }
}

#[tokio::main]
async fn main() {
    let stream = SomethingStream;
    let rtmp_context = RtmpContext::default();
    let handler_constructor = PhantomData::<SomethingHandler<SomethingStream>>;
    let runner = SomethingRunner::new(stream, rtmp_context, handler_constructor);
    let result = runner.await;

    assert!(result.is_ok());
}

Required Methods§

Source

fn new(stream: Arc<RW>) -> Self

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.

Implementors§