arpy_server/
lib.rs

1use std::future::Future;
2
3use arpy::{FnRemote, FnSubscription};
4use futures::{stream::BoxStream, Stream};
5pub use websocket::{WebSocketHandler, WebSocketRouter};
6
7pub mod websocket;
8
9/// An implementation of a remote function.
10///
11/// You shouldn't need to implement this, as a blanket implementation is
12/// provided for any `async` function or closure that takes a single
13/// [`FnRemote`] argument and returns the [`FnRemote::Output`].
14pub trait FnRemoteBody<Args>
15where
16    Args: FnRemote,
17{
18    type Fut: Future<Output = Args::Output> + Send;
19
20    /// Evaluate the function.
21    fn run(&self, args: Args) -> Self::Fut;
22}
23
24impl<Args, Fut, F> FnRemoteBody<Args> for F
25where
26    Args: FnRemote,
27    F: Fn(Args) -> Fut,
28    Fut: Future<Output = Args::Output> + Send,
29{
30    type Fut = Fut;
31
32    fn run(&self, args: Args) -> Self::Fut {
33        self(args)
34    }
35}
36
37/// An implementation of a subscription service.
38///
39/// You shouldn't need to implement this, as a blanket implementation is
40/// provided for any `async` function or closure that takes a single
41/// [`FnSubscription`] argument and returns a stream of
42/// [`FnSubscription::Item`].
43pub trait FnSubscriptionBody<Args>
44where
45    Args: FnSubscription,
46    Args::Item: 'static,
47    Args::Update: 'static,
48{
49    type Output: Stream<Item = Args::Item> + Send;
50
51    /// Evaluate the function.
52    fn run(
53        &self,
54        updates: impl Stream<Item = Args::Update> + Send + 'static,
55        args: Args,
56    ) -> (Args::InitialReply, Self::Output);
57}
58
59impl<Args, Output, F> FnSubscriptionBody<Args> for F
60where
61    Args: FnSubscription,
62    F: Fn(BoxStream<'static, Args::Update>, Args) -> (Args::InitialReply, Output),
63    Output: Stream<Item = Args::Item> + Send,
64    Args::Item: 'static,
65    Args::Update: 'static,
66{
67    type Output = Output;
68
69    fn run(
70        &self,
71        updates: impl Stream<Item = Args::Update> + Send + 'static,
72        args: Args,
73    ) -> (Args::InitialReply, Self::Output) {
74        self(Box::pin(updates), args)
75    }
76}