xref: /DragonOS/kernel/crates/unified-init/src/lib.rs (revision fae6e9ade46a52976ad5d099643d51cc20876448)
1 #![no_std]
2 #![allow(clippy::needless_return)]
3 
4 use system_error::SystemError;
5 pub use unified_init_macros as macros;
6 
7 /// 统一初始化器
8 #[derive(Debug)]
9 pub struct UnifiedInitializer {
10     function: &'static UnifiedInitFunction,
11     name: &'static str,
12 }
13 
14 impl UnifiedInitializer {
15     pub const fn new(
16         name: &'static str,
17         function: &'static UnifiedInitFunction,
18     ) -> UnifiedInitializer {
19         UnifiedInitializer { function, name }
20     }
21 
22     /// 调用初始化函数
23     pub fn call(&self) -> Result<(), SystemError> {
24         (self.function)()
25     }
26 
27     /// 获取初始化函数的名称
28     pub const fn name(&self) -> &'static str {
29         self.name
30     }
31 }
32 
33 pub type UnifiedInitFunction = fn() -> core::result::Result<(), SystemError>;
34 
35 /// 定义统一初始化器的分布式切片数组(私有)
36 #[macro_export]
37 macro_rules! define_unified_initializer_slice {
38     ($name:ident) => {
39         #[::linkme::distributed_slice]
40         static $name: [::unified_init::UnifiedInitializer] = [..];
41     };
42     () => {
43         compile_error!(
44             "define_unified_initializer_slice! requires at least one argument: slice_name"
45         );
46     };
47 }
48 
49 /// 定义统一初始化器的分布式切片数组(公开)
50 #[macro_export]
51 macro_rules! define_public_unified_initializer_slice {
52     ($name:ident) => {
53         #[::linkme::distributed_slice]
54         pub static $name: [::unified_init::UnifiedInitializer] = [..];
55     };
56     () => {
57         compile_error!(
58             "define_unified_initializer_slice! requires at least one argument: slice_name"
59         );
60     };
61 }
62 
63 /// 调用指定数组中的所有初始化器
64 #[macro_export]
65 macro_rules! unified_init {
66     ($initializer_slice:ident) => {
67         for initializer in $initializer_slice.iter() {
68             initializer.call().unwrap_or_else(|e| {
69                 log::error!("Failed to call initializer {}: {:?}", initializer.name(), e);
70             });
71         }
72     };
73 }
74