deno_features/
lib.rs

1// Copyright 2018-2025 the Deno authors. MIT license.
2
3mod r#gen;
4mod structs;
5
6use std::collections::BTreeSet;
7
8pub use r#gen::UNSTABLE_ENV_VAR_NAMES;
9pub use r#gen::UNSTABLE_FEATURES;
10pub use structs::UnstableFeatureKind;
11
12pub const JS_SOURCE: deno_core::FastStaticString =
13  deno_core::ascii_str_include!("./gen.js");
14
15pub type ExitCb = Box<dyn Fn(&str, &str) + Send + Sync>;
16
17#[allow(clippy::print_stderr)]
18#[allow(clippy::disallowed_methods)]
19fn exit(feature: &str, api_name: &str) {
20  eprintln!("Feature '{feature}' for '{api_name}' was not specified, exiting.");
21  std::process::exit(70);
22}
23
24pub struct FeatureChecker {
25  features: BTreeSet<&'static str>,
26  exit_cb: ExitCb,
27}
28
29impl Default for FeatureChecker {
30  fn default() -> Self {
31    Self {
32      features: BTreeSet::new(),
33      exit_cb: Box::new(exit),
34    }
35  }
36}
37
38impl FeatureChecker {
39  #[inline(always)]
40  pub fn check(&self, feature: &str) -> bool {
41    self.features.contains(feature)
42  }
43
44  pub fn enable_feature(&mut self, feature: &'static str) {
45    let inserted = self.features.insert(feature);
46    assert!(
47      inserted,
48      "Trying to enable a feature that is already enabled: {feature}",
49    );
50  }
51
52  #[inline(always)]
53  pub fn check_or_exit(&self, feature: &str, api_name: &str) {
54    if !self.check(feature) {
55      (self.exit_cb)(feature, api_name);
56    }
57  }
58
59  pub fn set_exit_cb(&mut self, cb: ExitCb) {
60    self.exit_cb = cb;
61  }
62}