async_event_streams_derive/
lib.rs1mod param;
29
30use param::{take_params, Param};
31use quote::quote;
32use syn::{parse::ParseStream, parse_macro_input, DeriveInput, Ident};
33
34extern crate proc_macro;
35
36#[proc_macro_derive(EventSink, attributes(event_sink))]
37pub fn derive_event_sink(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
38 let input: DeriveInput = parse_macro_input!(input);
39 match derive_event_sink_impl(input) {
40 Ok(stream) => stream,
41 Err(e) => e.into_compile_error(),
42 }
43 .into()
44}
45
46fn derive_event_sink_impl(mut input: DeriveInput) -> syn::Result<proc_macro2::TokenStream> {
47 let mut derives = Vec::new();
48 if let Some(params) = take_params::<StructParam>("event_sink", &mut input.attrs)? {
49 for param in params {
50 match param {
51 StructParam::Event(Ok(v)) => {
52 derives.push(derive_event_sink_for_event(&input.ident, v)?)
53 }
54 StructParam::Event(Err(e)) => return Err(e),
55 }
56 }
57 }
58 let mut res = proc_macro2::TokenStream::new();
59 res.extend(derives.into_iter());
60 Ok(res)
61}
62
63fn derive_event_sink_for_event(
64 struct_id: &Ident,
65 event_id: Ident,
66) -> syn::Result<proc_macro2::TokenStream> {
67 Ok(quote! {
68 #[async_trait]
69 impl EventSink<#event_id> for #struct_id {
70 type Error = <#struct_id as EventSinkExt<#event_id>>::Error;
71 async fn on_event_ref(
72 &self,
73 event: &#event_id,
74 source: Option<Arc<EventBox>>,
75 ) -> Result<(), Self::Error> {
76 <#struct_id as EventSinkExt<#event_id>>::on_event(&self, Cow::Borrowed(event), source).await
77 }
78 async fn on_event_owned(
79 &self,
80 event: #event_id,
81 source: Option<Arc<EventBox>>,
82 ) -> Result<(), Self::Error> {
83 <#struct_id as EventSinkExt<#event_id>>::on_event(&self, Cow::Owned(event), source).await
84 }
85 }
86 })
87}
88
89enum StructParam {
90 Event(Result<Ident, syn::Error>),
91}
92
93impl Param for StructParam {
94 fn default(name: Ident) -> syn::Result<Self> {
95 if name == "event" {
96 return Ok(StructParam::Event(Err(syn::Error::new(
97 name.span(),
98 "Event name expected",
99 ))));
100 } else {
101 Err(syn::Error::new(
102 name.span(),
103 "Unexpected parameter. Allowed value is 'event'",
104 ))
105 }
106 }
107 fn parse(&mut self, input: ParseStream) -> syn::Result<()> {
108 match self {
109 StructParam::Event(ref mut v) => *v = Ok(input.parse()?),
110 }
111 Ok(())
112 }
113}