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
//! Common types used across this crate
use crate::{socket_connection::peer::Peer};
use std::{
fmt::Debug,
sync::Arc,
};
use reactive_mutiny::prelude::{FullDuplexUniChannel, GenericUni, MutinyStream};
use crate::prelude::SocketConnection;
use crate::serde::ReactiveMessagingSerializer;
/// Concrete type of the `Stream`s this crate produces.\
/// Type for the `Stream` we create when reading from the remote peer.\
/// This type is intended to be used only for the first level of `dialog_processor_builder()`s you pass to
/// the [SocketClient] or [SocketServer], as Rust Generics isn't able to infer a generic `Stream` type
/// in this situation (in which the `Stream` is created inside the generic function itself).\
/// If your logic uses functions that receive `Stream`s, you'll want flexibility to do whatever you want
/// with the `Stream` (which would no longer be a `MutinyStream`), so declare such functions as:
/// ```no_compile
/// fn dialog_processor<RemoteStreamType: Stream<Item=SocketProcessorDerivedType<RemoteMessages>>>
/// (remote_messages_stream: RemoteStreamType) -> impl Stream<Item=LocalMessages> { ... }
pub type MessagingMutinyStream<GenericUniType: GenericUni> = MutinyStream<'static, GenericUniType::ItemType, GenericUniType::UniChannelType, GenericUniType::DerivedItemType>;
/// Adherents will, typically, also implement [ReactiveMessagingUnresponsiveSerializer].\
/// By upgrading your type with this trait, it is possible to build a "Responsive Processor", where the returned `Stream`
/// contains the messages to be sent as an answer to the remote peer.\
/// This trait, therefore, specifies (to the internal sender) how to handle special response cases, like "no answer" and "disconnection" messages.
pub trait ResponsiveMessages<LocalPeerMessages: ResponsiveMessages<LocalPeerMessages> + Send + PartialEq + Debug> {
/// Informs the internal sender if the given `processor_answer` is a "disconnect" message & command (issued by the messages processor logic)\
/// -- in which case, the network processor will send it and, immediately, close the connection.\
/// IMPLEMENTORS: #[inline(always)]
fn is_disconnect_message(processor_answer: &LocalPeerMessages) -> bool;
/// Tells if internal sender is the given `processor_answer` represents a "no message" -- a message that should produce no answer to the peer.\
/// IMPLEMENTORS: #[inline(always)]
fn is_no_answer_message(processor_answer: &LocalPeerMessages) -> bool;
}
/// Event issued by Composite Protocol Clients & Servers when connections are made or dropped
#[derive(Debug)]
pub enum ConnectionEvent<'a, StateType: Send + Sync + Clone + Debug> {
/// Happens when a connection is established with a remote party
Connected(&'a SocketConnection<StateType>),
/// Happens as soon as a disconnection is detected
Disconnected(&'a SocketConnection<StateType>),
/// Happens when the local code has commanded the service (and all opened connections) to stop
LocalServiceTermination,
}
/// Event issued by Composite Protocol Clients & Servers to their Reactive Processors.\
/// The user code may use those events to maintain a list of connected parties, be notified of stop/close/quit requests, init/de-init sessions, etc.
/// Note that the `Peer` objects received in those events may be used, at any time, to send messages to the remote party -- like "Shutting down. Goodbye".
/// IMPLEMENTATION NOTE: GAT traits (to reduce the number of generic parameters) couldn't be used here -- even after applying this compiler bug workaround https://github.com/rust-lang/rust/issues/102211#issuecomment-1513931928
/// -- the "error: implementation of `std::marker::Send` is not general enough" bug kept on popping up in user provided closures that called other async functions.
#[derive(Debug)]
pub enum ProtocolEvent<const CONFIG: u64,
LocalMessages: ReactiveMessagingSerializer<LocalMessages> + Send + Sync + PartialEq + Debug + 'static,
SenderChannel: FullDuplexUniChannel<ItemType=LocalMessages, DerivedItemType=LocalMessages> + Send + Sync,
StateType: Send + Sync + Clone + Debug + 'static = ()> {
/// Happens when a remote party is first made available to the reactive processor
/// (caused either by a new connection or by a reactive protocol transition)
PeerArrived { peer: Arc<Peer<CONFIG, LocalMessages, SenderChannel, StateType>> },
/// Happens when the remote party leaves the reactive processor
/// (caused either by a dropped connection or by a reactive protocol transition)
PeerLeft { peer: Arc<Peer<CONFIG, LocalMessages, SenderChannel, StateType>>, stream_stats: Arc<dyn reactive_mutiny::stream_executor::StreamExecutorStats + Sync + Send> },
/// Happens when the local code has commanded the service (and all opened connections) to stop
LocalServiceTermination,
}