aragog-macros 0.8.0

Macros for Aragog Crate
Documentation
use proc_macro2::{Span, TokenStream};
use syn::Ident;

use crate::to_tokenstream::ToTokenStream;

#[derive(Clone)]
pub struct HookData {
    pub func: Option<String>,
    pub database_access: Option<bool>,
    pub is_async: Option<bool>,
}

impl HookData {
    pub fn edit_func(&mut self, span: Span, func: &str) {
        if self.func.is_some() {
            emit_error!(span, "Can't have multiple `func` identifiers");
            return;
        }
        self.func = Some(func.to_string());
    }

    pub fn edit_db_access(&mut self, span: Span, value: bool) {
        if self.database_access.is_some() {
            emit_error!(span, "Can't have multiple `database_access` identifiers",);
        }
        self.database_access = Some(value);
    }

    pub fn edit_is_async(&mut self, span: Span, value: bool) {
        if self.is_async.is_some() {
            emit_error!(span, "Can't have multiple `is_async` identifiers");
        }
        self.is_async = Some(value);
    }
}

impl ToTokenStream for HookData {
    fn token_stream(self) -> TokenStream {
        let func = if let Some(f) = self.func {
            f
        } else {
            emit_call_site_error!("Missing function for hook");
            return TokenStream::new();
        };
        #[cfg(feature = "blocking")]
        let is_async = false;
        #[cfg(not(feature = "blocking"))]
        let is_async = self.is_async.unwrap_or(false);
        let db_access = self.database_access.unwrap_or(false);
        let func_ident = Ident::new(&func, Span::call_site());
        let func = if db_access {
            quote! {
                self.#func_ident(db_accessor)
            }
        } else {
            quote! {
                self.#func_ident()
            }
        };
        if is_async {
            quote! {
                #func.await?;
            }
        } else {
            quote! {
              #func?;
            }
        }
    }
}