From 5394b59547214e3fd88acb6be82cd274d097f704 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Pobiar=C5=BCyn?= Date: Fri, 29 Sep 2023 08:41:33 +0200 Subject: [PATCH] Fix events duplicates removal (#225) * Fix events duplicates removal * Fix field-less structs serialization (#226) --- examples/src/features/collecting_events.rs | 110 +++++++++++++++++++++ examples/src/features/mod.rs | 1 + lang/codegen/src/generator/module_item.rs | 18 ++-- lang/ir/src/utils.rs | 7 ++ 4 files changed, 126 insertions(+), 10 deletions(-) create mode 100644 examples/src/features/collecting_events.rs diff --git a/examples/src/features/collecting_events.rs b/examples/src/features/collecting_events.rs new file mode 100644 index 00000000..d910be08 --- /dev/null +++ b/examples/src/features/collecting_events.rs @@ -0,0 +1,110 @@ +#![allow(dead_code)] + +use odra::{ + prelude::string::{String, ToString}, + types::event::OdraEvent, + Event, Variable +}; + +#[derive(Event, PartialEq, Eq, Debug)] +struct Start; + +#[derive(Event, PartialEq, Eq, Debug)] +struct Stop; + +#[derive(Event, PartialEq, Eq, Debug)] +struct Info { + msg: String +} + +#[odra::module(events = [Start, Stop])] +struct Engine { + name: Variable +} + +impl Engine { + pub fn start(&self) { + Start.emit(); + } + + pub fn stop(&self) { + Stop.emit(); + } +} + +#[odra::module(events = [Info])] +struct Machine { + e1: Engine, + e2: Engine +} + +impl Machine { + pub fn start_first_engine(&self) { + self.e1.start(); + Info { + msg: "E1 started".to_string() + } + .emit(); + } + + pub fn start_second_engine(&self) { + self.e2.start(); + Info { + msg: "E2 started".to_string() + } + .emit(); + } +} + +#[cfg(all(test, feature = "mock-vm"))] +mod test { + use odra::{ + prelude::{string::ToString, vec}, + types::{ + contract_def::{Argument, Event}, + CLType + } + }; + + use super::{Engine, Machine}; + + #[test] + fn basic_events_collecting_works() { + let events = ::events(); + assert_eq!(2, events.len()); + + assert_eq!(vec![engine_event("Start"), engine_event("Stop")], events) + } + + #[test] + fn nested_events_collecting_works() { + // collects its own events and children modules events. + let events = ::events(); + assert_eq!(3, events.len()); + + assert_eq!( + vec![info_event(), engine_event("Start"), engine_event("Stop")], + events + ) + } + + fn engine_event(ident: &str) -> Event { + Event { + ident: ident.to_string(), + args: vec![] + } + } + + fn info_event() -> Event { + let arg = Argument { + ident: "msg".to_string(), + ty: CLType::String, + is_ref: false, + is_slice: false + }; + Event { + ident: "Info".to_string(), + args: vec![arg] + } + } +} diff --git a/examples/src/features/mod.rs b/examples/src/features/mod.rs index 071f9396..88f5674d 100644 --- a/examples/src/features/mod.rs +++ b/examples/src/features/mod.rs @@ -1,3 +1,4 @@ +pub mod collecting_events; pub mod composer; pub mod cross_calls; pub mod events; diff --git a/lang/codegen/src/generator/module_item.rs b/lang/codegen/src/generator/module_item.rs index d099d823..676e6abd 100644 --- a/lang/codegen/src/generator/module_item.rs +++ b/lang/codegen/src/generator/module_item.rs @@ -49,9 +49,9 @@ impl GenerateCode for ModuleStruct<'_> { #[cfg(not(target_arch = "wasm32"))] impl odra::types::contract_def::HasEvents for #struct_ident { fn events() -> odra::prelude::vec::Vec { - let mut events = odra::prelude::vec![]; + let mut events = odra::prelude::collections::BTreeSet::new(); #( - events.push(<#module_events as odra::types::event::OdraEvent>::schema()); + events.insert(<#module_events as odra::types::event::OdraEvent>::schema()); )* #( events.extend(<#submodules_events as odra::OdraItem>::events()); @@ -59,8 +59,7 @@ impl GenerateCode for ModuleStruct<'_> { #( events.extend(<#mappings_events as odra::OdraItem>::events()); )* - events.dedup(); - events + events.iter().map(Clone::clone).collect::>() } } } @@ -159,16 +158,15 @@ mod test { #[cfg(not (target_arch = "wasm32"))] impl odra::types::contract_def::HasEvents for Module { fn events() -> odra::prelude::vec::Vec { - let mut events = odra::prelude::vec![]; - events.push(::schema()); - events.push(::schema()); - events.push(::schema()); + let mut events = odra::prelude::collections::BTreeSet::new(); + events.insert(::schema()); + events.insert(::schema()); + events.insert(::schema()); events.extend(::events()); events.extend(::events()); events.extend(::events()); events.extend(::events()); - events.dedup(); - events + events.iter().map(Clone::clone).collect::>() } } }; diff --git a/lang/ir/src/utils.rs b/lang/ir/src/utils.rs index c1db4795..bc0648c5 100644 --- a/lang/ir/src/utils.rs +++ b/lang/ir/src/utils.rs @@ -9,6 +9,13 @@ pub fn extract_fields(input: DeriveInput) -> Result { fields: Fields::Named(named_fields), .. }) => named_fields, + Data::Struct(DataStruct { + fields: Fields::Unit, + .. + }) => FieldsNamed { + brace_token: Default::default(), + named: Default::default() + }, _ => { return Err(syn::Error::new_spanned( input,