rspack_core 0.100.0-rc.2

rspack core
Documentation
use napi::sys::{napi_env, napi_value};
use once_cell::sync::OnceCell;
use rspack_sources::BoxSource;
use rustc_hash::FxHashMap;

use super::BindingCell;
use crate::{AssetInfo, CodeGenerationResult, CodeGenerationResults, CompilationAsset, SourceType};

thread_local! {
  static NAPI_ALLOCATOR: OnceCell<Box<dyn NapiAllocator>> = OnceCell::default();
}

pub trait NapiAllocator {
  fn allocate_asset_info(
    &self,
    env: napi_env,
    val: &BindingCell<AssetInfo>,
  ) -> napi::Result<napi_value>;
  fn allocate_code_generation_results(
    &self,
    env: napi_env,
    val: &BindingCell<CodeGenerationResults>,
  ) -> napi::Result<napi_value>;
  fn allocate_code_generation_result(
    &self,
    env: napi_env,
    val: &BindingCell<CodeGenerationResult>,
  ) -> napi::Result<napi_value>;
  fn allocate_sources(
    &self,
    env: napi_env,
    val: &BindingCell<FxHashMap<SourceType, BoxSource>>,
  ) -> napi::Result<napi_value>;
  fn allocate_assets(
    &self,
    env: napi_env,
    val: &BindingCell<FxHashMap<String, CompilationAsset>>,
  ) -> napi::Result<napi_value>;
}

pub fn with_thread_local_allocator<T>(
  f: impl FnOnce(&Box<dyn NapiAllocator>) -> napi::Result<T>,
) -> napi::Result<T> {
  NAPI_ALLOCATOR.with(|once_cell| match once_cell.get() {
    Some(allocator) => f(allocator),
    None => Err(napi::Error::new(
      napi::Status::GenericFailure,
      "Allocator is not set in current thread",
    )),
  })
}

pub fn set_thread_local_allocator(allocator: Box<dyn NapiAllocator>) {
  NAPI_ALLOCATOR.with(|once_cell| {
    once_cell.get_or_init(|| allocator);
  })
}