use deno_core::v8;
use deno_core::ModuleSpecifier;
use serde::Serialize;
use std::cell::RefCell;
use std::thread;
use deno_terminal::colors;
#[derive(Copy, Clone)]
pub enum WorkerExecutionMode {
None,
Worker,
Run,
Repl,
Eval,
Test,
Bench,
Serve {
is_main: bool,
worker_count: Option<usize>,
},
Jupyter,
}
impl WorkerExecutionMode {
pub fn discriminant(&self) -> u8 {
match self {
WorkerExecutionMode::None => 0,
WorkerExecutionMode::Worker => 1,
WorkerExecutionMode::Run => 2,
WorkerExecutionMode::Repl => 3,
WorkerExecutionMode::Eval => 4,
WorkerExecutionMode::Test => 5,
WorkerExecutionMode::Bench => 6,
WorkerExecutionMode::Serve { .. } => 7,
WorkerExecutionMode::Jupyter => 8,
}
}
pub fn serve_info(&self) -> (Option<bool>, Option<usize>) {
match *self {
WorkerExecutionMode::Serve {
is_main,
worker_count,
} => (Some(is_main), worker_count),
_ => (None, None),
}
}
}
#[derive(Debug, Default, Clone, Copy)]
pub enum WorkerLogLevel {
Error = 1,
Warn = 2,
#[default]
Info = 3,
Debug = 4,
}
impl From<log::Level> for WorkerLogLevel {
fn from(value: log::Level) -> Self {
match value {
log::Level::Error => WorkerLogLevel::Error,
log::Level::Warn => WorkerLogLevel::Warn,
log::Level::Info => WorkerLogLevel::Info,
log::Level::Debug => WorkerLogLevel::Debug,
log::Level::Trace => WorkerLogLevel::Debug,
}
}
}
#[derive(Clone)]
pub struct BootstrapOptions {
pub deno_version: String,
pub args: Vec<String>,
pub cpu_count: usize,
pub log_level: WorkerLogLevel,
pub enable_op_summary_metrics: bool,
pub enable_testing_features: bool,
pub locale: String,
pub location: Option<ModuleSpecifier>,
pub no_color: bool,
pub is_stdout_tty: bool,
pub is_stderr_tty: bool,
pub color_level: deno_terminal::colors::ColorLevel,
pub unstable_features: Vec<i32>,
pub user_agent: String,
pub inspect: bool,
pub has_node_modules_dir: bool,
pub argv0: Option<String>,
pub node_debug: Option<String>,
pub node_ipc_fd: Option<i64>,
pub mode: WorkerExecutionMode,
pub serve_port: Option<u16>,
pub serve_host: Option<String>,
}
impl Default for BootstrapOptions {
fn default() -> Self {
let cpu_count = thread::available_parallelism()
.map(|p| p.get())
.unwrap_or(1);
let runtime_version = env!("CARGO_PKG_VERSION");
let user_agent = format!("Deno/{runtime_version}");
Self {
deno_version: runtime_version.to_string(),
user_agent,
cpu_count,
no_color: !colors::use_color(),
is_stdout_tty: deno_terminal::is_stdout_tty(),
is_stderr_tty: deno_terminal::is_stderr_tty(),
color_level: colors::get_color_level(),
enable_op_summary_metrics: Default::default(),
enable_testing_features: Default::default(),
log_level: Default::default(),
locale: "en".to_string(),
location: Default::default(),
unstable_features: Default::default(),
inspect: Default::default(),
args: Default::default(),
has_node_modules_dir: Default::default(),
argv0: None,
node_debug: None,
node_ipc_fd: None,
mode: WorkerExecutionMode::None,
serve_port: Default::default(),
serve_host: Default::default(),
}
}
}
#[derive(Serialize)]
struct BootstrapV8<'a>(
&'a str,
Option<&'a str>,
&'a [i32],
bool,
bool,
bool,
Option<&'a str>,
Option<&'a str>,
i32,
u16,
Option<&'a str>,
Option<bool>,
Option<usize>,
);
impl BootstrapOptions {
pub fn as_v8<'s>(
&self,
scope: &mut v8::HandleScope<'s>,
) -> v8::Local<'s, v8::Value> {
let scope = RefCell::new(scope);
let ser = deno_core::serde_v8::Serializer::new(&scope);
let (serve_is_main, serve_worker_count) = self.mode.serve_info();
let bootstrap = BootstrapV8(
&self.deno_version,
self.location.as_ref().map(|l| l.as_str()),
self.unstable_features.as_ref(),
self.inspect,
self.enable_testing_features,
self.has_node_modules_dir,
self.argv0.as_deref(),
self.node_debug.as_deref(),
self.mode.discriminant() as _,
self.serve_port.unwrap_or_default(),
self.serve_host.as_deref(),
serve_is_main,
serve_worker_count,
);
bootstrap.serialize(ser).unwrap()
}
}