use crate::message::MessageBytes; use crate::res::IFResult; use alloc::string::String; /// Some data that can be provided to the interface to send the message to a target. /// /// For IP this might be `IP:port`. /// Radio interface, for example, may not have the functionality of targeting, but that's fine pub(crate) type TargetingData = String; /// In an std environment we require that the interface can be send safely between threads #[cfg(not(feature = "std"))] pub trait InterfaceRequirements {} #[cfg(feature = "std")] pub trait InterfaceRequirements: Send + Sync {} /// An interface that can be used to pub trait Interface: InterfaceRequirements { /// Run one main loop iteration. /// On platforms that support concurrency, these functions will be run simultaneously for all interfaces. /// Most likely, this function will accept messages and save them somewhere internally to give out later in `Interface.receive()`. /// /// For systems that don't support concurrency, there can be only one interface in this function waits for a message (to avoid blocking). /// That's why it's necessary to check if it is the case for this interface, and it's done using function `Interface::has_blocking_main()` fn main_loop_iteration(&mut self) -> IFResult<()>; /// Check if `main_loop_iteration` stops execution and waits for a message fn has_blocking_main(&self) -> bool { false // hopefully... } /// Get some way of identification for this interface fn id(&self) -> &str; /// Send a message. If no `interface_data` is provided, we should consider it to be a broadcast. /// If, on the other hand, `interface_data` is not `None`, it should be used to send the message to the target. fn send( &mut self, message: &[u8], /*MessageBytes*/ interface_data: Option, ) -> IFResult<()>; /// Receive a message through this interface. Returns a result with an option of (message bytes, target). /// `None` means there is no message available at the time. /// The implementations of this function shouldn't wait for new messages, but fn receive(&mut self) -> IFResult>; } #[cfg(test)] pub mod test_interface { use crate::interface::{Interface, InterfaceRequirements, TargetingData}; use crate::message::MessageBytes; use crate::res::IFResult; use alloc::vec::Vec; #[derive(Default)] pub struct TestInterface { messages: Vec<(Vec, TargetingData)>, } impl InterfaceRequirements for TestInterface {} impl Interface for TestInterface { fn main_loop_iteration(&mut self) -> IFResult<()> { Ok(()) } fn id(&self) -> &str { "test_interface" } fn send(&mut self, message: &[u8], interface_data: Option) -> IFResult<()> { self.messages .push((Vec::from(message), interface_data.unwrap_or_default())); Ok(()) } fn receive(&mut self) -> IFResult> { Ok(self.messages.pop()) } } }