//! Here you'll only find the Spikes used to help in the top-down design of the server APIs during early development phases. //! Search elsewhere if you want real examples of how to use the resulting lib. //! All the structs & traits contained here are just representative simplifications of the real counter-parts, to help focusing //! on the design. mod uni; mod config; mod socket_server; use std::{marker::PhantomData, borrow::Borrow}; use uni::Uni; use uni::channel::ChannelZeroCopy; use config::ConstConfig; use socket_server::SocketServer; use crate::{socket_server::{GenericSocketServer, ZeroCopySocketServer, MovableSocketServer, ConnectionEvents}, uni::channel::{GenericChannel, ChannelMove}}; type LocalMessages = f64; type RemoteMessages = u32; fn main() { println!("Are you ready for the reactive-messaging client/server API Spikes?"); modality_1(); modality_2_and_3(); modality_4(); } /// specifying the types to their minimum in the closures fn modality_1() { const CONFIG: usize = ConstConfig::into(ConstConfig::Atomic(100)); const PROCESSOR_UNI_INSTRUMENTS: usize = 0; const PROCESSOR_BUFFER_SIZE: usize = 1024; const SENDER_BUFFER_SIZE: usize = 1024; type ProcessorChannelType = ChannelZeroCopy; type ProcessorUniType = Uni::; type SenderChannelType = ChannelMove; let _server = SocketServer:: { _phantom: PhantomData } .start( |_event| {}, |client_messages_stream| client_messages_stream.map(|_payload| 0.0) ); } /// With fully qualified types for external functions.\ /// Modality 2: using impl Iterator\ /// Modality 3: omitted, would be using the concrete alternative '_StreamType', avoiding the 'impl' fn modality_2_and_3() { const CONFIG: usize = ConstConfig::into(ConstConfig::Atomic(100)); const PROCESSOR_UNI_INSTRUMENTS: usize = 0; const PROCESSOR_BUFFER_SIZE: usize = 1024; const SENDER_BUFFER_SIZE: usize = 1024; type ProcessorChannelType = ChannelZeroCopy; type ProcessorUniType = Uni::; type SenderChannelType = ChannelMove; type ServerType = SocketServer; type ConnectionEventType = ConnectionEvents<>::ConnectionEventType>; type _StreamType = >::StreamType; type StreamItemType = >::StreamItemType; let _server = ServerType { _phantom: PhantomData } .start(connection_events_handler, processor); fn connection_events_handler(_event: ConnectionEventType) {} fn processor(client_messages_stream: /*_StreamType*/impl Iterator) -> impl Iterator { client_messages_stream.map(|payload| *payload as f64) } } /// Selectively starting a server for each channel/uni, while preserving the same processor functions fn modality_4 () { const CONFIG: usize = ConstConfig::into(ConstConfig::Atomic(100)); const PROCESSOR_UNI_INSTRUMENTS: usize = 0; const PROCESSOR_BUFFER_SIZE: usize = 1024; const SENDER_BUFFER_SIZE: usize = 1024; type AtomicServer = ZeroCopySocketServer; type AtomicStreamItemType = >::StreamItemType; type FullSyncServer = MovableSocketServer; type FullSyncStreamItemType = >::StreamItemType; // if atomic let _atomic_server = AtomicServer {_phantom: PhantomData} .start(connection_events_handler, processor:: /* Arc */); // if full sync let _full_sync_server = FullSyncServer {_phantom: PhantomData} .start(connection_events_handler, processor:: /* RemoteMessages */); fn connection_events_handler>(event: ConnectionEvents) { match event { ConnectionEvents::_Connected(_) => todo!(), ConnectionEvents::_Disconnected(_) => todo!(), ConnectionEvents::_IOError(_) => todo!(), } } fn processor>(client_messages_stream: impl Iterator) -> impl Iterator { client_messages_stream.map(|payload| *payload.borrow() as f64) } }