diff --git a/riker-macros/src/lib.rs b/riker-macros/src/lib.rs index 90cdd5ab..0eab98ba 100644 --- a/riker-macros/src/lib.rs +++ b/riker-macros/src/lib.rs @@ -5,8 +5,11 @@ use quote::quote; use syn::parse::{Parse, ParseStream, Result}; use syn::punctuated::Punctuated; use syn::spanned::Spanned; -use syn::token::{Colon2, Comma}; -use syn::{DeriveInput, Generics, PathSegment, TypePath}; +use syn::token::Comma; +use syn::{ + DeriveInput, Generics, QSelf, Type, TypeArray, TypeGroup, TypeParen, TypePath, TypePtr, + TypeReference, TypeSlice, TypeTuple, +}; struct MsgTypes { types: Vec, @@ -43,7 +46,7 @@ impl Parse for MsgTypes { types: vars .into_iter() .map(|t| MsgVariant { - name: get_name(&t.path.segments), + name: Ident::new(&get_path_name(&t), t.span()), mtype: t, }) .collect::>(), @@ -51,24 +54,52 @@ impl Parse for MsgTypes { } } -fn get_name(segments: &Punctuated) -> Ident { - let vname = segments - .iter() - .map(|seg| { - let ident = format!("{}", seg.ident); - ident - .split('_') - .map(|s| { - let mut s = s.to_string(); - if let Some(c) = s.get_mut(0..1) { - c.make_ascii_uppercase(); - } - s - }) - .collect::() - }) - .collect::(); - syn::Ident::new(&vname, segments.span()) +fn get_type_name(ty: &Type) -> String { + match ty { + Type::Path(path) => get_path_name(path), + Type::Array(TypeArray { elem, .. }) + | Type::Group(TypeGroup { elem, .. }) + | Type::Paren(TypeParen { elem, .. }) + | Type::Ptr(TypePtr { elem, .. }) + | Type::Reference(TypeReference { elem, .. }) + | Type::Slice(TypeSlice { elem, .. }) => get_type_name(elem.as_ref()), + Type::Tuple(TypeTuple { elems, .. }) => { + elems.iter().fold(String::new(), |mut acc, curr| { + acc.push_str(&get_type_name(&curr)); + acc + }) + } + _ => unreachable!(), + } +} + +fn get_path_name(type_path: &TypePath) -> String { + let mut vname = if let Some(QSelf { ty, .. }) = &type_path.qself { + get_type_name(ty.as_ref()) + } else { + String::new() + }; + vname.push_str( + &type_path + .path + .segments + .iter() + .map(|seg| { + let ident = format!("{}", seg.ident); + ident + .split('_') + .map(|s| { + let mut s = s.to_string(); + if let Some(c) = s.get_mut(0..1) { + c.make_ascii_uppercase(); + } + s + }) + .collect::() + }) + .collect::(), + ); + vname } #[proc_macro_attribute] diff --git a/riker-macros/tests/macro.rs b/riker-macros/tests/macro.rs index 4f5b4966..a6f7ec3e 100644 --- a/riker-macros/tests/macro.rs +++ b/riker-macros/tests/macro.rs @@ -149,7 +149,13 @@ fn run_generic_message_actor() { } } +pub trait TestTrait { + type TraitType; +} + mod test_mod { + use super::TestTrait; + #[derive(Clone, Debug)] pub struct GenericMessage { pub inner: T, @@ -157,9 +163,13 @@ mod test_mod { #[derive(Clone, Debug)] pub struct Message; + + impl TestTrait for Message { + type TraitType = String; + } } -#[actor(test_mod::GenericMessage, test_mod::Message)] +#[actor(test_mod::GenericMessage, ::TraitType)] #[derive(Clone, Default)] struct PathMsgActor; @@ -189,13 +199,13 @@ impl Receive> for PathMsgActor { } } -impl Receive for PathMsgActor { +impl Receive<::TraitType> for PathMsgActor { type Msg = PathMsgActorMsg; fn receive( &mut self, _ctx: &Context, - _msg: test_mod::Message, + _msg: ::TraitType, _sender: Option, ) { println!("message"); @@ -208,7 +218,7 @@ fn run_path_message_actor() { let act = sys.actor_of::("act").unwrap(); - let msg = PathMsgActorMsg::TestModMessage(test_mod::Message); + let msg = PathMsgActorMsg::TestModMessageTestTraitTraitType(String::from("test")); act.tell(msg, None); let generic_msg = PathMsgActorMsg::TestModGenericMessage(test_mod::GenericMessage {