private_event_proc_macro/
lib.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
use proc_macro::TokenStream;
use proc_macro_error::abort;
use syn::parse_macro_input;
use syn::Item;
use syn::ItemEnum;

// #[proc_macro_error]
#[proc_macro_attribute]
pub fn private_event(_attrs: TokenStream, input: TokenStream) -> TokenStream {
    let input = parse_macro_input!(input as Item);
    // let attr_args: proc_macro2::TokenStream = attrs.into();

    let ident = match &input {
        Item::Enum(ItemEnum { ident, .. }) => ident,
        _ => abort!(input, "private_event can only be used on Enums"),
    };

    let output = quote::quote! {
        #[derive(Serialize, Deserialize, SerializedBytes, Debug, private_event_sourcing::IntoStaticStr, Clone)]
        #[serde(tag = "type")]
        #input

        impl private_event_sourcing::EventType for #ident {
            fn event_type(&self) -> String {
                let s: &'static str = self.into();
                s.to_string()
            }
        }

        #[hdk_extern]
        pub fn send_new_events(events_hashes: BTreeSet<EntryHash>) -> ExternResult<()> {
            private_event_sourcing::send_new_events::<#ident>(events_hashes)
        }

        #[hdk_extern]
        pub fn receive_message_with_provenance(input: private_event_sourcing::ReceiveMessageWithProvenanceInput) -> ExternResult<()> {
            private_event_sourcing::receive_message::<#ident>(input.provenance, input.message)
        }

        #[hdk_extern]
        pub fn receive_message(message: private_event_sourcing::Message) -> ExternResult<()> {
            let provenance = call_info()?.provenance;
            private_event_sourcing::receive_message::<#ident>(provenance, message)
        }

        #[hdk_extern(infallible)]
        fn scheduled_tasks(_: Option<Schedule>) -> Option<Schedule> {
            if let Err(err) = private_event_sourcing::scheduled_tasks::<#ident>() {
                error!("Failed to perform scheduled tasks: {err:?}");
            }

            Some(Schedule::Persisted("0 */5 * * * * *".into())) // Every 5 minutes
        }
    };
    output.into()
}