sword-macros 0.3.0

Structured web framework built on top of tokio ecosystem, providing powerful features for building robust web applications.
Documentation
mod handle;

use super::shared::{CMetaStack, ControllerStruct, ParsedControllerKind};
use proc_macro::TokenStream;
use proc_macro2::TokenStream as TokenStream2;
use quote::quote;
use syn::Error;

pub use handle::expand_handle;

pub fn expand_event_handler(input: &ControllerStruct) -> syn::Result<TokenStream> {
    let ParsedControllerKind::EventHandler { source } = &input.kind else {
        return Err(Error::new_spanned(
            &input.name,
            "Expected an EventHandler controller struct",
        ));
    };

    let self_name = &input.name;
    let self_fields = &input.fields;
    let controller_name_str = self_name.to_string();

    let build_impl = crate::shared::gen_build(self_name, self_fields);
    let clone_impl = crate::shared::gen_clone(self_name, self_fields);

    CMetaStack::push("event_handler", "controller_name", &controller_name_str);

    let source_tokens = source.as_tokens();

    let expanded: TokenStream2 = quote! {
        #build_impl
        #clone_impl

        impl ::sword::internal::events::EventHandler for #self_name {}

        impl ::sword::internal::core::ControllerSpec for #self_name {
            fn kind() -> ::sword::internal::core::Controller {
                ::sword::internal::core::Controller::EventHandler
            }
        }

        const _: () = {
            ::sword::internal::inventory::submit! {
                ::sword::internal::events::EventControllerRegistrar {
                    handler_type_id: ::std::any::TypeId::of::<#self_name>(),
                    source: #source_tokens,
                    build: |state: &::sword::internal::core::State| {
                        let controller = <#self_name as ::sword::internal::core::Build>::build(state)
                            .unwrap_or_else(|err| {
                                ::sword::internal::core::sword_error! {
                                    title: "Failed to build EventHandler controller",
                                    reason: err,
                                    context: {
                                        "controller" => #controller_name_str,
                                    },
                                    hints: [
                                        "Ensure all controller dependencies are registered as providers or components",
                                    ],
                                }
                            });

                        state.insert::<#self_name>(controller);
                    },
                }
            }
        };
    };

    Ok(TokenStream::from(expanded))
}