From 1212a85127cc110db77a673dae23a9bdd4a0ffbb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Wo=C5=BAniak?= Date: Tue, 10 Sep 2024 10:59:00 +0200 Subject: [PATCH] wip use vec instead of map --- .../src/contract/communication/reply.rs | 70 +++++++++++++++++-- 1 file changed, 66 insertions(+), 4 deletions(-) diff --git a/sylvia-derive/src/contract/communication/reply.rs b/sylvia-derive/src/contract/communication/reply.rs index dc1c4a21..37f52ff8 100644 --- a/sylvia-derive/src/contract/communication/reply.rs +++ b/sylvia-derive/src/contract/communication/reply.rs @@ -1,4 +1,3 @@ -use std::collections::hash_map::Entry; use std::collections::HashMap; use convert_case::{Case, Casing}; @@ -218,15 +217,47 @@ impl<'a> ReplyVariants<'a> for MsgVariants<'a, GenericParam> { } } -struct ReplyData<'a> { +struct ReplyIdData<'a> { pub reply_id: Ident, - pub function_name: &'a Ident, - pub reply_on: ReplyOn, + pub handlers: Vec<(&'a Ident, ReplyOn)>, } +impl<'a> ReplyIdData<'a> { + pub fn new(variants: &'a MsgVariants<'a, GenericParam>) -> Self { + let mut : HashMap> = HashMap::new(); + + let reply_data: Vec<_> = variants + .variants() + .flat_map(ReplyVariant::as_reply_data) + .map(|(reply_id, function_name, reply_on)| { + match reply_id_to_data.get_key_value(&reply_id) { + Some((prev_reply_id, prev_value)) + if prev_value + .iter() + .any(|(_, prev_reply_on)| { + prev_reply_on.excludes(&reply_on) + }) => + { + prev_value.iter().for_each(|(prev_function_name, prev_reply_on)|{ + emit_error!(reply_id.span(), "Duplicated reply handler."; + note = prev_function_name.span() => format!("Previous definition of handler={} for reply_on={}", prev_reply_id.to_string(), prev_reply_on) + ) + }) + } + _ => { + let _ = reply_id_to_data.entry(reply_id) + .and_modify(|values| values.push((function_name, reply_on))) + .or_insert_with(|| vec![(function_name, reply_on)]); + }, + } }) + } + } + + trait ReplyVariant<'a> { fn as_handlers(&'a self) -> Vec<&'a Ident>; fn as_reply_data(&self) -> Vec<(Ident, &Ident, ReplyOn)>; + fn as_reply_id_data(&self,variants: &'a MsgVariants<'a, GenericParam>) -> Vec> ; } impl<'a> ReplyVariant<'a> for MsgVariant<'a> { @@ -249,6 +280,37 @@ impl<'a> ReplyVariant<'a> for MsgVariant<'a> { }) .collect() } + + fn as_reply_id_data(&self,variants: &'a MsgVariants<'a, GenericParam>) -> Vec> { + let mut reply_id_data: Vec<(Ident, &'a Ident, ReplyOn)> = vec![]; + + let reply_data: Vec<_> = variants + .variants() + .flat_map(ReplyVariant::as_reply_data) + .map(|(reply_id, function_name, reply_on)| { + match reply_id_data.iter().find(|data| data.0 == reply_id) + // match reply_id_data.get_key_value(&reply_id) { + Some((prev_reply_id, prev_value)) + if prev_value + .iter() + .any(|(_, prev_reply_on)| { + prev_reply_on.excludes(&reply_on) + }) => + { + prev_value.iter().for_each(|(prev_function_name, prev_reply_on)|{ + emit_error!(reply_id.span(), "Duplicated reply handler."; + note = prev_function_name.span() => format!("Previous definition of handler={} for reply_on={}", prev_reply_id.to_string(), prev_reply_on) + ) + }) + } + _ => { + let _ = reply_id_to_data.entry(reply_id) + .and_modify(|values| values.push((function_name, reply_on))) + .or_insert_with(|| vec![(function_name, reply_on)]); + }, + }}); + vec![] + } } /// Maps self to a reply id