odra-codegen 0.7.1

Code generators for Odra IR.
Documentation
use derive_more::From;
use odra_ir::EventItem as IrEventItem;
use proc_macro2::TokenStream;
use quote::quote;

use crate::GenerateCode;

use super::common;

const EVENT_PREFIX: &str = "event_";

#[derive(From)]
pub struct EventItem<'a> {
    event: &'a IrEventItem
}

impl GenerateCode for EventItem<'_> {
    fn generate_code(&self) -> TokenStream {
        let struct_ident = self.event.struct_ident();

        let struct_serialization_code = serialize_struct(self.event);
        let event_def = to_event_def(self.event);

        quote! {
            impl odra::types::event::OdraEvent for #struct_ident {
                fn emit(self) {
                    odra::contract_env::emit_event(self);
                }

                fn name() -> odra::prelude::string::String {
                    odra::prelude::string::String::from(stringify!(#struct_ident))
                }

                #[cfg(not(target_arch = "wasm32"))]
                fn schema() -> odra::types::contract_def::Event {
                    #event_def
                }
            }

            #struct_serialization_code
        }
    }
}

fn to_event_def(event: &IrEventItem) -> TokenStream {
    let struct_ident = event.struct_ident();
    let fields = event
        .fields_iter()
        .map(|field| {
            let field_ident = field.ident.as_ref().unwrap();
            let ty = &field.ty;
            let is_slice = matches!(ty, syn::Type::Slice(syn::TypeSlice { .. }));
            quote! {
                odra::types::contract_def::Argument {
                    ident: odra::prelude::string::String::from(stringify!(#field_ident)),
                    ty: <#ty as odra::types::CLTyped>::cl_type(),
                    is_ref: false,
                    is_slice: #is_slice
                },
            }
        })
        .collect::<TokenStream>();
    quote! {
        odra::types::contract_def::Event {
            ident: odra::prelude::string::String::from(stringify!(#struct_ident)),
            args: odra::prelude::vec![#fields]
        }
    }
}

fn serialize_struct(event: &IrEventItem) -> TokenStream {
    let struct_ident = event.struct_ident();
    let fields = event
        .fields_iter()
        .map(|f| f.ident.clone().unwrap())
        .collect::<Vec<_>>();

    common::serialize_struct(EVENT_PREFIX, struct_ident, &fields)
}