use std::cell::Cell;
#[derive(Clone, Copy)]
struct Config {
level: i64,
to_stderr: bool,
}
const DEFAULT: Config = Config {
level: 2, to_stderr: true,
};
thread_local! {
static CONFIG: Cell<Option<Config>> = const { Cell::new(None) };
}
fn get() -> Config {
CONFIG.with(|c| match c.get() {
Some(cfg) => cfg,
None => {
c.set(Some(DEFAULT));
DEFAULT
}
})
}
#[no_mangle]
pub extern "C-unwind" fn nova_rt_log_config_level() -> i64 {
get().level
}
#[no_mangle]
pub extern "C-unwind" fn nova_rt_log_config_to_stderr() -> i64 {
if get().to_stderr {
1
} else {
0
}
}
#[no_mangle]
pub extern "C-unwind" fn nova_rt_log_set_config(level: i64, to_stderr: i64) {
CONFIG.with(|c| {
c.set(Some(Config {
level,
to_stderr: to_stderr != 0,
}))
});
}
#[cfg(test)]
fn reset_for_test() {
CONFIG.with(|c| c.set(None));
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn an_unset_config_reads_as_the_default() {
reset_for_test();
assert_eq!(nova_rt_log_config_level(), 2);
assert_eq!(nova_rt_log_config_to_stderr(), 1);
}
#[test]
fn set_then_get_round_trips() {
reset_for_test();
nova_rt_log_set_config(4, 0);
assert_eq!(nova_rt_log_config_level(), 4);
assert_eq!(nova_rt_log_config_to_stderr(), 0);
}
#[test]
fn the_second_set_wins() {
reset_for_test();
nova_rt_log_set_config(0, 1);
nova_rt_log_set_config(3, 0);
assert_eq!(nova_rt_log_config_level(), 3);
assert_eq!(nova_rt_log_config_to_stderr(), 0);
}
}