xboot 0.1.25

static variables like module-level database connections can be initialized asynchronously before the program starts. / 在程序启动前通过异步函数初始化静态变量,如模块级数据库连接。
Documentation
#![feature(concat_idents)]

use aok::Result;
pub use gensym::gensym;
pub use linkme::distributed_slice;
pub use paste::paste;
use static_init::constructor;
pub use tokio;

#[constructor(0)]
extern "C" fn cinit() {
  loginit::init();
}

pub type Task = tokio::task::JoinHandle<Result<()>>;

pub type AsyncFn = fn() -> Task;

#[distributed_slice]
pub static XBOOT: [AsyncFn];

pub async fn init() -> Result<()> {
  for i in XBOOT {
    i().await??;
  }
  Ok(())
}

#[macro_export]
macro_rules! add {
  ($init:expr) => {
    $crate::gensym! {$crate::add! {$init}}
  };
  ($id:expr, $init:expr) => {
    $crate::paste! {
    fn [<xboot_init_ $id>]() -> $crate::Task {
      $crate::tokio::task::spawn(async {
        $init;
        Ok(())
      })
    }
    #[$crate::distributed_slice($crate::XBOOT)]
    static [<XBOOT_INIT_ $id>]: $crate::AsyncFn = [<xboot_init_ $id>];
    }
  };
}