aragog-macros 0.8.0

Macros for Aragog Crate
Documentation
use syn::{Field, Path};

use crate::derives::record::hook_data::HookData;
use crate::derives::record::operation::HookOperation;
use crate::parse_attribute::ParseAttribute;
use crate::toolbox::expect_no_field_name;
use proc_macro2::Span;
use syn::spanned::Spanned;

#[derive(Debug, Clone)]
pub enum HookType {
    BeforeAll,
    BeforeWrite,
    BeforeSave,
    BeforeCreate,
    BeforeDelete,
    AfterAll,
    AfterWrite,
    AfterSave,
    AfterCreate,
    AfterDelete,
}

#[derive(Clone)]
pub struct Hook {
    pub hook_type: HookType,
    pub hook_data: HookData,
}

impl ParseAttribute for Hook {
    type AttributeOperation = HookOperation;

    fn init(path: &Path, field: Option<&Field>) -> Option<Self> {
        let ident = path.get_ident()?;
        expect_no_field_name(path.span(), field)?;
        let hook_type = match ident.to_string().as_str() {
            "before_all" => HookType::BeforeAll,
            "before_write" => HookType::BeforeWrite,
            "before_save" => HookType::BeforeSave,
            "before_create" => HookType::BeforeCreate,
            "before_delete" => HookType::BeforeDelete,
            "after_all" => HookType::AfterAll,
            "after_write" => HookType::AfterWrite,
            "after_save" => HookType::AfterSave,
            "after_create" => HookType::AfterCreate,
            "after_delete" => HookType::AfterDelete,
            _ => return None,
        };
        Some(Self {
            hook_type,
            hook_data: HookData {
                func: None,
                database_access: None,
                is_async: None,
            },
        })
    }

    fn field(&self) -> Option<String> {
        None
    }

    fn add_operation(&mut self, span: Span, operation: Self::AttributeOperation) {
        match operation {
            HookOperation::Func(func) => self.hook_data.edit_func(span, &func),
            HookOperation::IsAsync(v) => self.hook_data.edit_is_async(span, v),
            HookOperation::DbAccess(v) => self.hook_data.edit_db_access(span, v),
        }
    }

    fn validate(&self, span: Span) -> bool {
        if self.hook_data.func.is_none() {
            emit_error!(span, "Missing function for {:?} hook", self.hook_type);
            false
        } else {
            true
        }
    }
}