diff --git a/satrs/Cargo.toml b/satrs/Cargo.toml index 58755cd..c5f69b7 100644 --- a/satrs/Cargo.toml +++ b/satrs/Cargo.toml @@ -25,11 +25,12 @@ thiserror = { version = "2", default-features = false } hashbrown = { version = ">=0.14, <=0.15", optional = true } static_cell = { version = "2" } -heapless = { version = "0.9" } +heapless = { version = "0.9", optional = true } dyn-clone = { version = "1", optional = true } downcast-rs = { version = "2", default-features = false, optional = true } bus = { version = "2.2", optional = true } crossbeam-channel = { version = "0.5", default-features = false, optional = true } +postcard = { version = "1", features = ["alloc"] } serde = { version = "1", default-features = false, optional = true } socket2 = { version = "0.6", features = ["all"], optional = true } arbitrary-int = "2" @@ -48,7 +49,7 @@ tempfile = "3" version = "1" [features] -default = ["std"] +default = ["std", "heapless"] std = [ "downcast-rs/std", "alloc", diff --git a/satrs/src/event_man_2.rs b/satrs/src/event_man_2.rs index 10bfbcd..9b00d39 100644 --- a/satrs/src/event_man_2.rs +++ b/satrs/src/event_man_2.rs @@ -48,13 +48,13 @@ //! The [PUS event](https://egit.irs.uni-stuttgart.de/rust/sat-rs/src/branch/main/satrs-example/src/pus/event.rs) //! module and the generic [events module](https://egit.irs.uni-stuttgart.de/rust/sat-rs/src/branch/main/satrs-example/src/events.rs) //! show how the event management modules can be integrated into a more complex software. -use core::{marker::PhantomData, option::Iter}; - use crate::{ ComponentId, - events2::{Event, EventDynParam, EventId, GroupId}, + events2::{Event, EventId, GroupId}, queue::GenericSendError, }; +use core::marker::PhantomData; +use core::slice::Iter; #[cfg(feature = "alloc")] pub use alloc_mod::*; @@ -70,17 +70,16 @@ pub enum ListenerKey { All, } -#[derive(Debug)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[derive(Debug, serde::Serialize, serde::Deserialize)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] -pub struct EventMessage { +pub struct EventMessage { sender_id: ComponentId, event: EventInstance, } impl EventMessage { - pub fn new(sender_id: ComponentId, event: &EventInstance) -> Self { - EventMessage { sender_id, event: event.clone() } + pub fn new(sender_id: ComponentId, event: EventInstance) -> Self { + EventMessage { sender_id, event } } pub fn sender_id(&self) -> ComponentId { @@ -283,10 +282,9 @@ impl< if let Some(ids) = self.listener_map.get_listener_ids(key) { for id in ids { if let Some(sender) = self.sender_map.get_send_event_provider(id) { - if let Err(e) = sender.send(EventMessage::new( - event_msg.sender_id, - event_msg.event.clone(), - )) { + if let Err(e) = sender + .send(EventMessage::new(event_msg.sender_id, event_msg.event.clone())) + { error_handler(event_msg, EventRoutingError::Send(e)); } else { num_recipients += 1; @@ -320,11 +318,13 @@ pub mod alloc_mod { use alloc::vec::Vec; use hashbrown::HashMap; + use crate::events2::EventErasedAlloc; + use super::*; /// Helper type which constrains the sender map and listener map generics to the [DefaultSenderMap] /// and the [DefaultListenerMap]. It uses regular mpsc channels as the message queue backend. - pub type EventManagerWithMpsc = EventManager< + pub type EventManagerWithMpsc = EventManager< EventDynParamReceiverMpsc, DefaultSenderMap, EventInstance>, DefaultListenerMap, @@ -336,7 +336,7 @@ pub mod alloc_mod { /// and the [DefaultListenerMap]. It uses /// [bounded mpsc senders](https://doc.rust-lang.org/std/sync/mpsc/struct.SyncSender.html) as the /// message queue backend. - pub type EventManagerWithBoundedMpsc = EventManager< + pub type EventManagerWithBoundedMpsc = EventManager< EventDynParamReceiverMpsc, DefaultSenderMap, EventInstance>, DefaultListenerMap, @@ -417,7 +417,7 @@ pub mod alloc_mod { /// Simple implementation which uses a [HashMap] internally. pub struct DefaultSenderMap< EventSenderInstance: EventSender, - EventInstance: Event = EventDynParam, + EventInstance: Event, > { senders: HashMap, phantom: PhantomData, @@ -460,7 +460,10 @@ pub mod alloc_mod { #[cfg(feature = "std")] pub mod std_mod { - use crate::{events2::EventHeapless, queue::GenericReceiveError}; + use crate::{ + events2::{EventErasedAlloc, EventHeapless}, + queue::GenericReceiveError, + }; use super::*; use std::sync::mpsc; @@ -483,7 +486,7 @@ pub mod std_mod { } } - pub type EventDynParamReceiverMpsc = mpsc::Receiver>; + pub type EventDynParamReceiverMpsc = mpsc::Receiver>; pub type EventHeaplessReceiverMpsc = mpsc::Receiver>>; @@ -563,9 +566,9 @@ pub mod std_mod { } } - pub type EventDynParamSenderMpsc = EventSenderMpsc; + pub type EventDynParamSenderMpsc = EventSenderMpsc; pub type EventHeaplessSenderMpsc = EventSenderMpsc>; - pub type EventDynParamSenderMpscBounded = EventSenderMpscBounded; + pub type EventDynParamSenderMpscBounded = EventSenderMpscBounded; pub type EventHeaplessSenderMpscBounded = EventSenderMpscBounded>; } @@ -575,52 +578,46 @@ mod tests { use arbitrary_int::u14; use super::*; - use crate::events2::Severity; - use crate::params::{ParamsHeapless, ParamsRaw}; + use crate::events2::{EventErasedAlloc, Severity}; use crate::pus::test_util::{TEST_COMPONENT_ID_0, TEST_COMPONENT_ID_1}; - use std::format; use std::sync::mpsc; - use std::vec::Vec; const TEST_GROUP_ID_0: u14 = u14::new(0); + const TEST_GROUP_ID_1: u14 = u14::new(1); - #[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)] - pub enum TestEventIds { - TestInfo, - TestError, + #[derive(Copy, Clone, PartialEq, Eq, Debug, Hash, serde::Serialize, serde::Deserialize)] + pub enum TestEvent { + Info, + Error, + InfoWithParams(u16), + OtherGroup, } - impl Event for TestEventIds { + impl Event for TestEvent { fn id(&self) -> EventId { match self { - TestEventIds::TestInfo => EventId::new( - Severity::Info, - TEST_GROUP_ID_0, - TestEventIds::TestInfo as u16, - ), - TestEventIds::TestError => EventId::new( - Severity::High, - TEST_GROUP_ID_0, - TestEventIds::TestError as u16, - ), + TestEvent::Info => EventId::new(Severity::Info, TEST_GROUP_ID_0, 0), + TestEvent::Error => EventId::new(Severity::High, TEST_GROUP_ID_0, 1), + TestEvent::InfoWithParams(_) => EventId::new(Severity::Info, TEST_GROUP_ID_0, 2), + TestEvent::OtherGroup => EventId::new(Severity::Info, TEST_GROUP_ID_1, 0), } } } fn check_next_event( - expected: EventDynParam, - receiver: &mpsc::Receiver>, - ) -> Option> { + expected: TestEvent, + receiver: &mpsc::Receiver>, + ) { if let Ok(event_msg) = receiver.try_recv() { - assert_eq!(event_msg.event, expected); - return event_msg.event.parameters().map(|p| p.to_vec()); + assert_eq!(event_msg.event.id(), expected.id()); + let event: TestEvent = postcard::from_bytes(event_msg.event().raw()).unwrap(); + assert_eq!(event, expected); } - None } fn check_handled_event( - res: EventRoutingResult, - expected: &EventDynParam, + res: EventRoutingResult, + expected: &EventErasedAlloc, expected_num_sent: u32, expected_sender_id: ComponentId, ) { @@ -637,7 +634,7 @@ mod tests { } fn generic_event_man() -> ( - mpsc::Sender>, + mpsc::Sender>, EventManagerWithMpsc, ) { let (event_sender, event_receiver) = mpsc::channel(); @@ -647,197 +644,197 @@ mod tests { #[test] fn test_basic() { let (event_sender, mut event_man) = generic_event_man(); - //let event_grp_0 = EventU::new(Severity::Info, 0, 0); - //let event_grp_1_0 = EventU32::new(Severity::High, 1, 0); let (single_event_sender, single_event_receiver) = mpsc::channel(); let single_event_listener = EventSenderMpsc::new(0, single_event_sender); - event_man.subscribe_single( - TestEventIds::TestInfo.id(), - single_event_listener.target_id(), - ); + event_man.subscribe_single(TestEvent::Info.id(), single_event_listener.target_id()); event_man.add_sender(single_event_listener); let (group_event_sender_0, group_event_receiver_0) = mpsc::channel(); let group_event_listener = EventDynParamSenderMpsc::new(1, group_event_sender_0); event_man.subscribe_group( - TestEventIds::TestError.id().group_id(), + TestEvent::OtherGroup.id().group_id(), group_event_listener.target_id(), ); event_man.add_sender(group_event_listener); - let error_handler = |event_msg: &EventMessage, e: EventRoutingError| { + let error_handler = |event_msg: &EventMessage, e: EventRoutingError| { panic!("routing error occurred for event {:?}: {:?}", event_msg, e); }; - let event_grp_0 = - EventDynParam::new_no_params(TestEventIds::TestInfo.id()); - let event_grp_1 = - EventDynParam::new_no_params(TestEventIds::TestError.id()); + let event_grp_0 = EventErasedAlloc::new(&TestEvent::Info); + let event_grp_1 = EventErasedAlloc::new(&TestEvent::OtherGroup); // Test event with one listener event_sender .send(EventMessage::new( TEST_COMPONENT_ID_0.id(), - &event_grp_0 + event_grp_0.clone(), )) .expect("Sending single error failed"); let res = event_man.try_event_handling(&error_handler); check_handled_event(res, &event_grp_0, 1, TEST_COMPONENT_ID_0.id()); - check_next_event(event_grp_0, &single_event_receiver); + check_next_event(TestEvent::Info, &single_event_receiver); // Test event which is sent to all group listeners event_sender - .send(EventMessage::new(TEST_COMPONENT_ID_1.id(), &event_grp_1)) + .send(EventMessage::new( + TEST_COMPONENT_ID_1.id(), + event_grp_1.clone(), + )) .expect("Sending group error failed"); let res = event_man.try_event_handling(&error_handler); check_handled_event(res, &event_grp_1, 1, TEST_COMPONENT_ID_1.id()); - check_next_event(event_grp_1, &group_event_receiver_0); + check_next_event(TestEvent::OtherGroup, &group_event_receiver_0); } #[test] fn test_with_basic_params() { - let error_handler = |event_msg: &EventMessage, e: EventRoutingError| { + let error_handler = |event_msg: &EventMessage, e: EventRoutingError| { panic!("routing error occurred for event {:?}: {:?}", event_msg, e); }; let (event_sender, mut event_man) = generic_event_man(); - let event_grp_0 = EventU32::new(Severity::Info, 0, 0); + let event_0 = TestEvent::InfoWithParams(5); let (single_event_sender, single_event_receiver) = mpsc::channel(); let single_event_listener = EventSenderMpsc::new(0, single_event_sender); - event_man.subscribe_single(&event_grp_0, single_event_listener.target_id()); + event_man.subscribe_single(event_0.id(), single_event_listener.target_id()); event_man.add_sender(single_event_listener); + let event_0_erased = EventErasedAlloc::new(&event_0); event_sender - .send(EventMessage::new_with_params( + .send(EventMessage::new( TEST_COMPONENT_ID_0.id(), - event_grp_0, - &Params::Heapless((2_u32, 3_u32).into()), + event_0_erased.clone(), )) .expect("Sending group error failed"); let res = event_man.try_event_handling(&error_handler); - check_handled_event(res, event_grp_0, 1, TEST_COMPONENT_ID_0.id()); - let aux = check_next_event(event_grp_0, &single_event_receiver); - assert!(aux.is_some()); - let aux = aux.unwrap(); - if let Params::Heapless(ParamsHeapless::Raw(ParamsRaw::U32Pair(pair))) = aux { - assert_eq!(pair.0, 2); - assert_eq!(pair.1, 3); - } else { - panic!("{}", format!("Unexpected auxiliary value type {:?}", aux)); - } + check_handled_event(res, &event_0_erased, 1, TEST_COMPONENT_ID_0.id()); + check_next_event(event_0, &single_event_receiver); } /// Test listening for multiple groups #[test] fn test_multi_group() { - let error_handler = |event_msg: &EventMessageU32, e: EventRoutingError| { + let error_handler = |event_msg: &EventMessage, e: EventRoutingError| { panic!("routing error occurred for event {:?}: {:?}", event_msg, e); }; let (event_sender, mut event_man) = generic_event_man(); let res = event_man.try_event_handling(error_handler); assert!(matches!(res, EventRoutingResult::Empty)); - let event_grp_0 = EventU32::new(Severity::Info, 0, 0); - let event_grp_1_0 = EventU32::new(Severity::High, 1, 0); + let event_grp_0 = TestEvent::Info; + let event_grp_1 = TestEvent::OtherGroup; let (event_grp_0_sender, event_grp_0_receiver) = mpsc::channel(); - let event_grp_0_and_1_listener = EventU32SenderMpsc::new(0, event_grp_0_sender); + let event_grp_0_and_1_listener = EventSenderMpsc::new(0, event_grp_0_sender); event_man.subscribe_group( - event_grp_0.group_id(), + event_grp_0.id().group_id(), event_grp_0_and_1_listener.target_id(), ); event_man.subscribe_group( - event_grp_1_0.group_id(), + event_grp_1.id().group_id(), event_grp_0_and_1_listener.target_id(), ); event_man.add_sender(event_grp_0_and_1_listener); + let event_grp_0_erased = EventErasedAlloc::new(&event_grp_0); + let event_grp_1_erased = EventErasedAlloc::new(&event_grp_1); event_sender - .send(EventMessage::new(TEST_COMPONENT_ID_0.id(), event_grp_0)) + .send(EventMessage::new( + TEST_COMPONENT_ID_0.id(), + event_grp_0_erased.clone(), + )) .expect("Sending Event Group 0 failed"); event_sender - .send(EventMessage::new(TEST_COMPONENT_ID_1.id(), event_grp_1_0)) + .send(EventMessage::new( + TEST_COMPONENT_ID_1.id(), + event_grp_1_erased.clone(), + )) .expect("Sendign Event Group 1 failed"); let res = event_man.try_event_handling(error_handler); - check_handled_event(res, event_grp_0, 1, TEST_COMPONENT_ID_0.id()); + check_handled_event(res, &event_grp_0_erased, 1, TEST_COMPONENT_ID_0.id()); let res = event_man.try_event_handling(error_handler); - check_handled_event(res, event_grp_1_0, 1, TEST_COMPONENT_ID_1.id()); + check_handled_event(res, &event_grp_1_erased, 1, TEST_COMPONENT_ID_1.id()); check_next_event(event_grp_0, &event_grp_0_receiver); - check_next_event(event_grp_1_0, &event_grp_0_receiver); + check_next_event(event_grp_1, &event_grp_0_receiver); } /// Test listening to the same event from multiple listeners. Also test listening /// to both group and single events from one listener #[test] fn test_listening_to_same_event_and_multi_type() { - let error_handler = |event_msg: &EventMessageU32, e: EventRoutingError| { + let error_handler = |event_msg: &EventMessage, e: EventRoutingError| { panic!("routing error occurred for event {:?}: {:?}", event_msg, e); }; let (event_sender, mut event_man) = generic_event_man(); - let event_0 = EventU32::new(Severity::Info, 0, 5); - let event_1 = EventU32::new(Severity::High, 1, 0); + let event_0 = TestEvent::Info; + let event_1 = TestEvent::OtherGroup; + //let event_0 = EventU32::new(Severity::Info, 0, 5); + //let event_1 = EventU32::new(Severity::High, 1, 0); let (event_0_tx_0, event_0_rx_0) = mpsc::channel(); let (event_0_tx_1, event_0_rx_1) = mpsc::channel(); - let event_listener_0 = EventU32SenderMpsc::new(0, event_0_tx_0); - let event_listener_1 = EventU32SenderMpsc::new(1, event_0_tx_1); + let event_listener_0 = EventSenderMpsc::new(0, event_0_tx_0); + let event_listener_1 = EventSenderMpsc::new(1, event_0_tx_1); let event_listener_0_sender_id = event_listener_0.target_id(); - event_man.subscribe_single(&event_0, event_listener_0_sender_id); + event_man.subscribe_single(event_0.id(), event_listener_0_sender_id); event_man.add_sender(event_listener_0); let event_listener_1_sender_id = event_listener_1.target_id(); - event_man.subscribe_single(&event_0, event_listener_1_sender_id); + event_man.subscribe_single(event_0.id(), event_listener_1_sender_id); event_man.add_sender(event_listener_1); + let event_0_erased = EventErasedAlloc::new(&event_0); + let event_1_erased = EventErasedAlloc::new(&event_1); event_sender - .send(EventMessage::new(TEST_COMPONENT_ID_0.id(), event_0)) + .send(EventMessage::new(TEST_COMPONENT_ID_0.id(), event_0_erased.clone())) .expect("Triggering Event 0 failed"); let res = event_man.try_event_handling(error_handler); - check_handled_event(res, event_0, 2, TEST_COMPONENT_ID_0.id()); + check_handled_event(res, &event_0_erased, 2, TEST_COMPONENT_ID_0.id()); check_next_event(event_0, &event_0_rx_0); check_next_event(event_0, &event_0_rx_1); - event_man.subscribe_group(event_1.group_id(), event_listener_0_sender_id); + event_man.subscribe_group(event_1.id().group_id(), event_listener_0_sender_id); event_sender - .send(EventMessage::new(TEST_COMPONENT_ID_0.id(), event_0)) + .send(EventMessage::new(TEST_COMPONENT_ID_0.id(), event_0_erased.clone())) .expect("Triggering Event 0 failed"); event_sender - .send(EventMessage::new(TEST_COMPONENT_ID_1.id(), event_1)) + .send(EventMessage::new(TEST_COMPONENT_ID_1.id(), event_1_erased.clone())) .expect("Triggering Event 1 failed"); // 3 Events messages will be sent now let res = event_man.try_event_handling(error_handler); - check_handled_event(res, event_0, 2, TEST_COMPONENT_ID_0.id()); + check_handled_event(res, &event_0_erased, 2, TEST_COMPONENT_ID_0.id()); let res = event_man.try_event_handling(error_handler); - check_handled_event(res, event_1, 1, TEST_COMPONENT_ID_1.id()); + check_handled_event(res, &event_1_erased, 1, TEST_COMPONENT_ID_1.id()); // Both the single event and the group event should arrive now check_next_event(event_0, &event_0_rx_0); check_next_event(event_1, &event_0_rx_0); // Do double insertion and then remove duplicates - event_man.subscribe_group(event_1.group_id(), event_listener_0_sender_id); - event_man.remove_duplicates(&ListenerKey::Group(event_1.group_id())); + event_man.subscribe_group(event_1.id().group_id(), event_listener_0_sender_id); + event_man.remove_duplicates(&ListenerKey::Group(event_1.id().group_id())); event_sender - .send(EventMessage::new(TEST_COMPONENT_ID_0.id(), event_1)) + .send(EventMessage::new(TEST_COMPONENT_ID_0.id(), event_1_erased.clone())) .expect("Triggering Event 1 failed"); let res = event_man.try_event_handling(error_handler); - check_handled_event(res, event_1, 1, TEST_COMPONENT_ID_0.id()); + check_handled_event(res, &event_1_erased, 1, TEST_COMPONENT_ID_0.id()); } #[test] fn test_all_events_listener() { - let error_handler = |event_msg: &EventMessageU32, e: EventRoutingError| { + let error_handler = |event_msg: &EventMessage, e: EventRoutingError| { panic!("routing error occurred for event {:?}: {:?}", event_msg, e); }; let (event_sender, event_receiver) = mpsc::channel(); let mut event_man = EventManagerWithMpsc::new(event_receiver); - let event_0 = EventDynParam::new_no_params(TestEventIds::TestInfo.id()); - let event_1 = EventDynParam::new_no_params(TestEventIds::TestError.id()); + let event_0 = TestEvent::Info; + let event_1 = TestEvent::Error; let (event_0_tx_0, all_events_rx) = mpsc::channel(); - let all_events_listener = EventU32SenderMpsc::new(0, event_0_tx_0); + let all_events_listener = EventSenderMpsc::new(0, event_0_tx_0); event_man.subscribe_all(all_events_listener.target_id()); event_man.add_sender(all_events_listener); event_sender - .send(EventMessage::new(TEST_COMPONENT_ID_0.id(), event_0)) + .send(EventMessage::new(TEST_COMPONENT_ID_0.id(), event_0.into())) .expect("Triggering event 0 failed"); event_sender - .send(EventMessage::new(TEST_COMPONENT_ID_1.id(), event_1)) + .send(EventMessage::new(TEST_COMPONENT_ID_1.id(), event_1.into())) .expect("Triggering event 1 failed"); let res = event_man.try_event_handling(error_handler); - check_handled_event(res, event_0, 1, TEST_COMPONENT_ID_0.id()); + check_handled_event(res, &event_0.into(), 1, TEST_COMPONENT_ID_0.id()); let res = event_man.try_event_handling(error_handler); - check_handled_event(res, event_1, 1, TEST_COMPONENT_ID_1.id()); + check_handled_event(res, &event_1.into(), 1, TEST_COMPONENT_ID_1.id()); check_next_event(event_0, &all_events_rx); check_next_event(event_1, &all_events_rx); } @@ -845,17 +842,18 @@ mod tests { #[test] fn test_bounded_event_sender_queue_full() { let (event_sender, _event_receiver) = mpsc::sync_channel(3); - let event_sender = EventU32SenderMpscBounded::new(1, event_sender, 3); + let test_event = TestEvent::Info; + let event_sender = EventSenderMpscBounded::::new(1, event_sender, 3); event_sender - .send(EventMessage::new(TEST_COMPONENT_ID_0.id(), TEST_EVENT)) + .send(EventMessage::new(TEST_COMPONENT_ID_0.id(), test_event.into())) .expect("sending test event failed"); event_sender - .send(EventMessage::new(TEST_COMPONENT_ID_0.id(), TEST_EVENT)) + .send(EventMessage::new(TEST_COMPONENT_ID_0.id(), test_event.into())) .expect("sending test event failed"); event_sender - .send(EventMessage::new(TEST_COMPONENT_ID_0.id(), TEST_EVENT)) + .send(EventMessage::new(TEST_COMPONENT_ID_0.id(), test_event.into())) .expect("sending test event failed"); - let error = event_sender.send(EventMessage::new(TEST_COMPONENT_ID_0.id(), TEST_EVENT)); + let error = event_sender.send(EventMessage::new(TEST_COMPONENT_ID_0.id(), test_event.into())); if let Err(e) = error { assert!(matches!(e, GenericSendError::QueueFull(Some(3)))); } else { @@ -865,9 +863,10 @@ mod tests { #[test] fn test_bounded_event_sender_rx_dropped() { let (event_sender, event_receiver) = mpsc::sync_channel(3); - let event_sender = EventU32SenderMpscBounded::new(1, event_sender, 3); + let test_event = TestEvent::Info; + let event_sender = EventSenderMpscBounded::::new(1, event_sender, 3); drop(event_receiver); - if let Err(e) = event_sender.send(EventMessage::new(TEST_COMPONENT_ID_0.id(), TEST_EVENT)) { + if let Err(e) = event_sender.send(EventMessage::new(TEST_COMPONENT_ID_0.id(), test_event.into())) { assert!(matches!(e, GenericSendError::RxDisconnected)); } else { panic!("Expected error"); diff --git a/satrs/src/events.rs b/satrs/src/events.rs index f3fc88d..1194087 100644 --- a/satrs/src/events.rs +++ b/satrs/src/events.rs @@ -85,7 +85,7 @@ impl HasSeverity for SeverityHigh { const SEVERITY: Severity = Severity::High; } -pub trait GenericEvent: Copy + Clone { +pub trait GenericEvent: EcssEnumeration + Copy + Clone { type Raw; type GroupId; type UniqueId; diff --git a/satrs/src/events2.rs b/satrs/src/events2.rs index 53f7d12..577d8ae 100644 --- a/satrs/src/events2.rs +++ b/satrs/src/events2.rs @@ -29,13 +29,9 @@ //! ``` use core::fmt::Debug; use core::hash::Hash; -use core::marker::PhantomData; -use core::option::Iter; use arbitrary_int::{prelude::*, u14}; - -use crate::ComponentId; -use crate::queue::GenericSendError; +use spacepackets::ByteConversionError; /// Using a type definition allows to change this to u64 in the future more easily pub type LargestEventRaw = u32; @@ -100,11 +96,8 @@ impl TryFrom for Severity { } } -pub trait Event: Clone { +pub trait Event: Clone{ fn id(&self) -> EventId; - fn parameters(&self) -> Option<&[u8]> { - None - } } pub type GroupId = u14; @@ -162,61 +155,101 @@ impl From for EventId { #[derive(Debug, Clone, PartialEq, Eq)] #[cfg(feature = "alloc")] -pub struct EventDynParam { +pub struct EventErasedAlloc { id: EventId, - parameters: Option>, + event_raw: alloc::vec::Vec, } #[cfg(feature = "alloc")] -impl EventDynParam { - pub fn new(id: EventId, parameters: Option>) -> Self { - Self { id, parameters } - } - - pub fn new_no_params(id: EventId) -> Self { +impl EventErasedAlloc { + pub fn new(event: &(impl serde::Serialize + Event)) -> Self { Self { - id, - parameters: None, + id: event.id(), + event_raw: postcard::to_allocvec(event).unwrap(), } } + + #[inline] + pub fn raw(&self) -> &[u8] { + &self.event_raw + } } #[cfg(feature = "alloc")] -impl Event for EventDynParam { +impl From for EventErasedAlloc { + fn from(event: T) -> Self { + Self::new(&event) + } +} + +#[cfg(feature = "alloc")] +impl Event for EventErasedAlloc { fn id(&self) -> EventId { self.id } - - fn parameters(&self) -> Option<&[u8]> { - self.parameters.as_deref() - } } #[derive(Debug, Clone, PartialEq, Eq)] pub struct EventHeapless { id: EventId, - parameters: Option>, + event_raw: heapless::vec::Vec, } impl Event for EventHeapless { fn id(&self) -> EventId { self.id } - - fn parameters(&self) -> Option<&[u8]> { - self.parameters.as_deref() - } } impl EventHeapless { - pub fn new(id: EventId, parameters: Option>) -> Self { - Self { id, parameters } - } - - pub fn new_no_params(id: EventId) -> Self { - Self { - id, - parameters: None, + pub fn new(event: &(impl serde::Serialize + Event)) -> Result { + let ser_size = postcard::experimental::serialized_size(event).unwrap(); + if ser_size < N { + return Err(ByteConversionError::ToSliceTooSmall { + found: N, + expected: ser_size, + }); } + let mut vec = heapless::Vec::::new(); + vec.resize(N, 0); + postcard::to_slice(event, vec.as_mut_slice()).unwrap(); + Ok(Self { + id: event.id(), + event_raw: vec, + }) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use std::mem::size_of; + + fn assert_size(_: T, val: usize) { + assert_eq!(size_of::(), val); + } + + #[derive(Debug, Copy, Clone)] + pub enum TestEvent { + Info, + Error, + } + + impl Event for TestEvent { + fn id(&self) -> EventId { + match self { + TestEvent::Info => EventId::new(Severity::Info, u14::new(0), 0), + TestEvent::Error => EventId::new(Severity::High, u14::new(1), 1), + } + } + } + + #[test] + fn test_normal_event_getters() { + assert_eq!(TestEvent::Info.id().severity(), Severity::Info); + assert_eq!(TestEvent::Info.id().unique_id(), 0); + assert_eq!(TestEvent::Info.id().group_id().value(), 0); + let raw_event = TestEvent::Info.id().raw(); + assert_eq!(raw_event, 0x00000000); } } diff --git a/satrs/src/lib.rs b/satrs/src/lib.rs index c3e8f99..7a64c37 100644 --- a/satrs/src/lib.rs +++ b/satrs/src/lib.rs @@ -16,11 +16,11 @@ #![no_std] #![cfg_attr(docsrs, feature(doc_auto_cfg))] #[cfg(feature = "alloc")] -extern crate alloc; -#[cfg(feature = "alloc")] extern crate downcast_rs; #[cfg(any(feature = "std", test))] extern crate std; +#[cfg(any(feature = "alloc", test))] +extern crate alloc; pub mod action; #[cfg(feature = "alloc")]