sheave_client/client.rs
1use std::{
2 future::Future,
3 io::Result as IOResult,
4 marker::PhantomData,
5 pin::{
6 Pin,
7 pin
8 },
9 sync::Arc,
10 task::{
11 Context as FutureContext,
12 Poll
13 }
14};
15use tokio::io::{
16 AsyncRead,
17 AsyncWrite
18};
19use sheave_core::handlers::{
20 HandlerConstructor,
21 RtmpContext,
22 StreamWrapper
23};
24
25/// # The client instance of the Sheave
26///
27/// This consists of:
28///
29/// * Some stream instance which can both of read and write.
30/// * Context data in the client.
31/// * Some type parameter which implemented the [`HandlerConstructor`] trait.
32///
33/// The client wraps streams into [`Arc`] as a way of sharing streams among communication steps.
34/// And also wraps contexts because of the same purpose.
35///
36/// The client makes any foreign handler to be able to construct via the [`PhantomData`], where a type parameter of [`PhantomData`] requires to implement the [`HandlerConstructor`] trait.
37/// That is, its type parameter behaves as the constructor injection.
38///
39/// ## Examples
40///
41/// ```rust
42/// use std::{
43/// io::Result as IOResult,
44/// marker::PhantomData,
45/// pin::Pin,
46/// sync::Arc,
47/// task::{
48/// Context as FutureContext,
49/// Poll
50/// }
51/// };
52/// use tokio::io::{
53/// AsyncRead,
54/// AsyncWrite
55/// };
56/// use sheave_core::handlers::{
57/// AsyncHandler,
58/// HandlerConstructor,
59/// RtmpContext,
60/// StreamWrapper,
61/// VecStream
62/// };
63/// use sheave_client::Client;
64///
65/// struct SomethingHandler<RW: AsyncRead + AsyncWrite + Unpin>(Arc<StreamWrapper<RW>>);
66///
67/// impl<RW: AsyncRead + AsyncWrite + Unpin> AsyncHandler for SomethingHandler<RW> {
68/// fn poll_handle(self: Pin<&mut Self>, _cx: &mut FutureContext<'_>, _rtmp_context: &mut RtmpContext) -> Poll<IOResult<()>> {
69/// Poll::Ready(Ok(()))
70/// }
71/// }
72///
73/// impl<RW: AsyncRead + AsyncWrite + Unpin> HandlerConstructor<StreamWrapper<RW>> for SomethingHandler<RW> {
74/// fn new(stream: Arc<StreamWrapper<RW>>) -> Self {
75/// Self(stream)
76/// }
77/// }
78///
79/// #[tokio::main]
80/// async fn main() {
81/// let stream = VecStream::default();
82/// let rtmp_context = RtmpContext::default();
83/// let mut client = Client::new(stream, rtmp_context, PhantomData::<SomethingHandler<VecStream>>);
84/// let result = client.await;
85/// assert!(result.is_ok())
86/// }
87/// ```
88///
89/// [`Arc`]: std::sync::Arc
90/// [`PhantomData`]: std::marker::PhantomData
91/// [`HandlerConstructor`]: sheave_core::handlers::HandlerConstructor
92#[derive(Debug)]
93pub struct Client<RW, C>
94where
95 RW: AsyncRead + AsyncWrite + Unpin,
96 C: HandlerConstructor<StreamWrapper<RW>>
97{
98 stream: Arc<StreamWrapper<RW>>,
99 rtmp_context: Arc<RtmpContext>,
100 handler_constructor: PhantomData<C>
101}
102
103impl<RW, C> Client<RW, C>
104where
105 RW: AsyncRead + AsyncWrite + Unpin,
106 C: HandlerConstructor<StreamWrapper<RW>>
107{
108 /// Constructs a Client instance.
109 pub fn new(stream: RW, rtmp_context: RtmpContext, handler_constructor: PhantomData<C>) -> Self {
110 Self {
111 stream: Arc::new(StreamWrapper::new(stream)),
112 rtmp_context: Arc::new(rtmp_context),
113 handler_constructor
114 }
115 }
116}
117
118impl<RW, C> Future for Client<RW, C>
119where
120 RW: AsyncRead + AsyncWrite + Unpin,
121 C: HandlerConstructor<StreamWrapper<RW>>
122{
123 type Output = IOResult<()>;
124
125 fn poll(self: Pin<&mut Self>, cx: &mut FutureContext<'_>) -> Poll<Self::Output> {
126 pin!(C::new(Arc::clone(&self.stream))).poll_handle(cx, self.rtmp_context.make_weak_mut())
127 }
128}