reactive-messaging 0.4.1

Reactive client/server communications, focused on high performance
//! SERializers & DEserializers (traits & implementations) for our [SocketServer]

mod mmap_serde;

use std::fmt::Debug;
pub use mmap_serde::*;

mod variable_binary_serde;
pub use variable_binary_serde::*;

mod textual_serde;
pub use textual_serde::*;


/// Trait that should be implemented by enums that model the "local messages" to be sent to the remote peer --
/// "local messages" may either be messages generated by the server or by the client, depending on if you're building a server or client.\
/// This trait specifies if & how we should:
///   * warn the peer if the received input has problems or if it should be silently ignored;
///   * inform the peer if any wrong input was sent.
pub trait ReactiveMessagingConfig<LocalMessages> {

    /// Called whenever the local processor found an error -- such as "we are too busy to process your request at the moment".
    /// If any, the returned message (enum variant) should be as descriptive as possible,
    /// as it will be sent in response to the remote party.\
    /// IMPLEMENTORS: #[inline(always)]
    #[inline(always)]
    fn processor_error_message(_err: String) -> Option<LocalMessages> {
        // By default, we do not inform the peer if a local processor error occurred.
        // However, implementors are encouraged to do so.
        None
    }

    /// Called when the local processor detects that the received input is invalid and should be ignored or cause the connection to close.
    /// If any, the returned message (enum variant) should be as descriptive as possible, as it will be sent in response to the remote party.\
    /// IMPLEMENTORS: #[inline(always)]
    #[inline(always)]
    fn input_error_message(_err: String) -> Option<LocalMessages> {
        // By default, we do not inform the peer if they sent a bad message.
        // However, implementors are encouraged to do so.
        None
    }
}

/// NOTE: Users of this crate are likely not to want to use this trait directly. See, instead:
///  - [ReactiveMessagingRkyvSerializer<>]
///  - [ReactiveMessageMemoryMappable]
///  - [ReactiveMessagingRonSerializer<>].
///
/// Specifies how to `serialize()` `LocalMessages`
pub trait ReactiveMessagingSerializer<LocalMessages>: Send + Sync + 'static {

    /// Local messages serializer: transforms a strong typed `local_message` into a sequence of bytes, putting it in `buffer`.\
    /// IMPLEMENTORS: #[inline(always)]
    fn serialize(local_message: &LocalMessages, buffer: &mut Vec<u8>);
}

/// NOTE: Users of this crate are likely not to want to use this trait directly. See, instead:
///  - [ReactiveMessagingRkyvFastDeserializer<>]
///  - [ReactiveMessagingRkyvSafeDeserializer<>]
///  - [ReactiveMessageMemoryMappable]
///  - [ReactiveMessagingTextualDeserializer<>].
///
/// Trait that should be implemented by enums that model the "remote messages" to be consumed by a "Responsive Processor" --
/// "remote messages" may either be messages produced by the remote server or by the remote client (when we are implementing the opposite peer).\
/// This trait, therefore, specifies how to `deserialize()` enum variants received by the remote peer.
pub trait ReactiveMessagingDeserializer<RemoteMessages>: Send + Sync + 'static {

    /// This is a version of `RemoteMessages` after it is deserialized.
    /// Sometimes it will be a copied version of the original -- for textual wires;
    /// Other times, it will be a reference to the original type -- mmap binary;
    /// And, in special cases, it will be a reference to totally different type -- `rkyv`. 
    /// NOTE: to satisfy this condition when using `rkyv`, use '#[archive_attr(derive(Debug))]' in your type
    type DeserializedRemoteMessages: Send + Sync + PartialEq + Debug + 'static;
    
    /// For zero-copy deserializers -- such as `rkyv` -- validating the input is a separate process,
    /// since we need to validate just once and deserializing (a.k.a., accessing the reference) is zero-cost
    /// -- so wrappers don't need to store the "deserialized" reference and, thus, need this method.
    /// IMPLEMENTORS: #[inline(always)]
    fn validate(remote_message: &[u8]) -> Result<(), crate::prelude::Error>;

    /// Remote messages deserializer: transforms a serialized `remote_message` into a type able to access all info from `RemoteMessages`.\
    /// IMPLEMENTORS: #[inline(always)]
    fn deserialize(remote_message: &[u8]) -> Result<Self::DeserializedRemoteMessages, crate::prelude::Error>;

    /// Remote messages deserializer: transforms a serialized `remote_message` into a type able to access all info from `RemoteMessages`.\
    /// IMPLEMENTORS: #[inline(always)]
    fn deserialize_as_ref(remote_message: &[u8]) -> Result<&Self::DeserializedRemoteMessages, crate::prelude::Error>;

}