pass_it_on/
interfaces.rs

1//! Interfaces for the server and client
2
3use crate::notifications::Notification;
4use crate::Error;
5use async_trait::async_trait;
6use dyn_clone::DynClone;
7use std::fmt::Debug;
8use std::time::Duration;
9use tokio::sync::{broadcast, mpsc, watch};
10
11#[cfg(all(unix, any(feature = "pipe-client", feature = "pipe-server", feature = "pipe")))]
12pub mod pipe;
13
14#[cfg(any(feature = "http-client", feature = "http-server"))]
15pub mod http;
16
17#[allow(dead_code)]
18pub(crate) const SECOND: Duration = Duration::from_secs(1);
19#[allow(dead_code)]
20pub(crate) const NANOSECOND: Duration = Duration::from_nanos(1);
21
22/// A data structure that can be deserialized and converted into an [`Interface`].
23#[typetag::deserialize(tag = "type")]
24pub trait InterfaceConfig: Debug {
25    /// Convert this `InterfaceConfig` into an [`Interface`].
26    fn to_interface(&self) -> Result<Box<dyn Interface + Send>, Error>;
27}
28
29/// A data structure that contains information and functions needed to communicate on a particular interface between the server and client.
30#[async_trait]
31pub trait Interface: DynClone + Send + Debug {
32    /// Implements the server receiving notifications from the `Interface`.
33    async fn receive(&self, interface_tx: mpsc::Sender<String>, shutdown: watch::Receiver<bool>) -> Result<(), Error>;
34
35    /// Implements the client sending notifications to the `Interface`.
36    async fn send(
37        &self,
38        interface_rx: broadcast::Receiver<Notification>,
39        shutdown: watch::Receiver<bool>,
40    ) -> Result<(), Error>;
41}
42
43dyn_clone::clone_trait_object!(Interface);
44
45#[cfg(feature = "server")]
46pub(crate) async fn setup_server_interfaces(
47    interfaces: Vec<Box<dyn Interface + Send>>,
48    interface_tx: mpsc::Sender<String>,
49    shutdown: watch::Receiver<bool>,
50) -> Result<(), Error> {
51    for interface in interfaces {
52        interface.receive(interface_tx.clone(), shutdown.clone()).await?;
53    }
54    Ok(())
55}
56
57#[cfg(feature = "client")]
58pub(crate) async fn setup_client_interfaces(
59    interfaces: Vec<Box<dyn Interface + Send>>,
60    interface_rx: broadcast::Receiver<Notification>,
61    shutdown: watch::Receiver<bool>,
62) -> Result<(), Error> {
63    for interface in interfaces {
64        interface.send(interface_rx.resubscribe(), shutdown.clone()).await?
65    }
66    Ok(())
67}