Files
asterinas/kernel/libs/comp-sys/component-macro/src/lib.rs
2024-02-28 16:30:48 +08:00

88 lines
2.2 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// SPDX-License-Identifier: MPL-2.0
//This crate defines the component system related macros.
//!
#![feature(proc_macro_diagnostic)]
#![allow(dead_code)]
#![forbid(unsafe_code)]
mod init_comp;
mod priority;
use init_comp::ComponentInitFunction;
use proc_macro::TokenStream;
use quote::quote;
use syn::parse_macro_input;
pub(crate) const COMPONENT_FILE_NAME: &str = "Components.toml";
/// Register a function to be called when the component system is initialized. The function should not public.
///
/// Example:
/// ```rust
/// #[init_component]
/// fn init() -> Result<(), component::ComponentInitError> {
/// Ok(())
/// }
///
/// ```
///
/// It will expand to
/// ```rust
/// fn init() -> Result<(), component::ComponentInitError> {
/// Ok(())
/// }
///
/// const fn file() -> &'static str{
/// file!()
/// }
///
/// component::submit!(component::ComponentRegistry::new(&init,file()));
/// ```
/// The priority will calculate automatically
///
#[proc_macro_attribute]
pub fn init_component(_: TokenStream, input: TokenStream) -> proc_macro::TokenStream {
let function = parse_macro_input!(input as ComponentInitFunction);
let function_name = &function.function_name;
quote! {
#function
const fn file() -> &'static str{
file!()
}
component::submit!(component::ComponentRegistry::new(&#function_name,file()));
}
.into()
}
/// Automatically generate all component information required by the component system.
///
/// It mainly uses the output of the command `cargo metadata` to automatically generate information about all components, and also checks whether `Components.toml` contains all the components.
///
/// It is often used with `component::init_all`.
///
/// Example:
///
/// ```rust
/// component::init_all(component::parse_metadata!());
/// ```
///
#[proc_macro]
pub fn parse_metadata(_: TokenStream) -> proc_macro::TokenStream {
let out = priority::component_generate();
let path = priority::get_component_toml_path();
quote! {
{
include_str!(#path);
extern crate alloc;
alloc::vec![
#(component::ComponentInfo::new #out),*
]
}
}
.into()
}