1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
//! Traits for building [`InputConnector`], [`OutputConnector`], and [`Service`]
//!
//! [`InputConnector`]: interface::InputConnector
//! [`OutputConnector`]: interface::OutputConnector
//! [`Service`]: interface::Service
use crate::channel::{ClosedChannel, Receiver, Sender};
use async_trait::async_trait;
/// Implement an input connector.
/// An input connector is in change of creating [`Message`] and sending asynchronously
/// to the services.
///
/// If the sender return a [`ClosedChannel`] error, it is expected to propagate this error.
///
/// See default implementations in [`connectors`]
///
/// Do not forget to add the [`mod@async_trait`] crate when implement this trait
///
/// [`connectors`]: crate::connectors
/// [`Message`]: crate::message::Message
///
/// # Example
/// ```rust
/// use service_io::interface::{InputConnector};
/// use service_io::channel::{ClosedChannel, Sender};
/// use service_io::message::{Message};
///
/// use async_trait::async_trait;
///
/// struct MyInput;
///
/// #[async_trait]
/// impl InputConnector for MyInput {
/// async fn run(self: Box<Self>, sender: Sender) -> Result<(), ClosedChannel> {
/// // Load phase
/// // ...
/// loop {
/// // Get the message from your implementation
/// // ...
/// let message = Message::default();
///
/// // Send the message to the service
/// sender.send(message).await?;
/// }
/// }
/// }
/// ```
#[async_trait]
pub trait InputConnector {
async fn run(self: Box<Self>, sender: Sender) -> Result<(), ClosedChannel>;
}
/// Implement an output connector.
/// An output connector is waiting asynchronously for messages comming from the services
/// and deliver them.
///
/// If the receiver return a [`ClosedChannel`] error, it is expected to propagate this error.
///
/// See default implementations in [`connectors`]
///
/// Do not forget to add the [`mod@async_trait`] crate when implement this trait
///
/// [`connectors`]: crate::connectors
/// [`Message`]: crate::message::Message
///
/// # Example
/// ```rust
///
/// use service_io::interface::{OutputConnector};
/// use service_io::channel::{ClosedChannel, Receiver};
///
/// use async_trait::async_trait;
///
/// struct MyOutput;
///
/// #[async_trait]
/// impl OutputConnector for MyOutput {
/// async fn run(self: Box<Self>, mut receiver: Receiver) -> Result<(), ClosedChannel> {
/// // Load phase
/// // ...
/// loop {
/// // Get the message from the service...
/// let message = receiver.recv().await?;
///
/// // Do whatever your output impl must do. i.e send the message by email
/// // ...
/// }
/// }
/// }
/// ```
#[async_trait]
pub trait OutputConnector {
async fn run(self: Box<Self>, receiver: Receiver) -> Result<(), ClosedChannel>;
}
/// Implement a service.
/// A Service is an entity that processes input messages asynchronously and send output messages
/// asynchronously.
///
/// If both, sender or receiver return a [`ClosedChannel`] error,
/// it is expected to propagate this error.
///
/// See default implementations in [`services`]
///
/// Do not forget to add the [`mod@async_trait`] crate when implement this trait
///
/// [`services`]: crate::services
///
/// # Example
/// ```rust
/// use service_io::interface::{Service};
/// use service_io::channel::{ClosedChannel, Receiver, Sender};
///
/// use async_trait::async_trait;
///
/// struct MyService;
///
/// #[async_trait]
/// impl Service for MyService {
/// async fn run(self: Box<Self>, mut input: Receiver, output: Sender) -> Result<(), ClosedChannel> {
/// // Load phase
/// // ...
/// loop {
/// // Get the message from the input connector.
/// let message = input.recv().await?;
///
/// // Do whatever your service impl must do.
/// // ...
///
/// // Send the message to the output connector.
/// output.send(message).await?;
/// }
/// }
/// }
/// ```
#[async_trait]
pub trait Service {
async fn run(self: Box<Self>, input: Receiver, output: Sender) -> Result<(), ClosedChannel>;
}