12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970 |
- extern crate proc_macro;
- use quote::quote;
- use syn::parse_macro_input;
- /// The event attribute allows a struct to be used with
- /// [emit!](./macro.emit.html) so that programs can log significant events in
- /// their programs that clients can subscribe to. Currently, this macro is for
- /// structs only.
- #[proc_macro_attribute]
- pub fn event(
- _args: proc_macro::TokenStream,
- input: proc_macro::TokenStream,
- ) -> proc_macro::TokenStream {
- let event_strct = parse_macro_input!(input as syn::ItemStruct);
- let event_name = &event_strct.ident;
- let discriminator: proc_macro2::TokenStream = {
- let discriminator_preimage = format!("event:{}", event_name.to_string());
- let mut discriminator = [0u8; 8];
- discriminator.copy_from_slice(
- &anchor_syn::hash::hash(discriminator_preimage.as_bytes()).to_bytes()[..8],
- );
- format!("{:?}", discriminator).parse().unwrap()
- };
- proc_macro::TokenStream::from(quote! {
- #[derive(anchor_lang::__private::EventIndex, AnchorSerialize, AnchorDeserialize)]
- #event_strct
- impl anchor_lang::Event for #event_name {
- fn data(&self) -> Vec<u8> {
- let mut d = #discriminator.to_vec();
- d.append(&mut self.try_to_vec().unwrap());
- d
- }
- }
- impl anchor_lang::Discriminator for #event_name {
- fn discriminator() -> [u8; 8] {
- #discriminator
- }
- }
- })
- }
- /// Creates an event that can be subscribed to by clients. Calling this method
- /// will internally borsh serialize the [event](./attr.event.html), base64
- /// encode the bytes, and then add a [msg!](../solana_program/macro.msg.html)
- /// log to the transaction.
- #[proc_macro]
- pub fn emit(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
- let data: proc_macro2::TokenStream = input.into();
- proc_macro::TokenStream::from(quote! {
- {
- let data = anchor_lang::Event::data(&#data);
- let msg_str = &anchor_lang::__private::base64::encode(data);
- anchor_lang::solana_program::msg!(msg_str);
- }
- })
- }
- // EventIndex is a marker macro. It functionally does nothing other than
- // allow one to mark fields with the `#[index]` inert attribute, which is
- // used to add metadata to IDLs.
- #[proc_macro_derive(EventIndex, attributes(index))]
- pub fn derive_event(_item: proc_macro::TokenStream) -> proc_macro::TokenStream {
- proc_macro::TokenStream::from(quote! {})
- }
|