use std::sync::atomic::{AtomicI64, Ordering};
use chrono::Utc;
const NOT_SET_VALUE: i64 = -1;
pub mod telemetry_global_static {
use super::*;
pub static mut START_TS_MICROS: AtomicI64 = AtomicI64::new(NOT_SET_VALUE);
pub static mut END_TS_MICROS: AtomicI64 = AtomicI64::new(NOT_SET_VALUE);
pub static mut AVG_RESPONSE_TIME_MICROS: AtomicI64 = AtomicI64::new(NOT_SET_VALUE);
pub fn set_start_ts() {
let current_ts_ms = Utc::now().timestamp_micros();
unsafe {
START_TS_MICROS.store(current_ts_ms, Ordering::SeqCst);
};
}
fn get_start_ts() -> Option<i64> {
let start_ts_ms = unsafe { START_TS_MICROS.load(Ordering::SeqCst) };
if start_ts_ms == NOT_SET_VALUE {
None
} else {
Some(start_ts_ms)
}
}
pub fn set_end_ts() {
let current_ts_ms = Utc::now().timestamp_micros();
unsafe {
END_TS_MICROS.store(current_ts_ms, Ordering::SeqCst);
};
if let Some(start_ts) = get_start_ts() {
let elapsed_ms = current_ts_ms - start_ts;
let saved_avg_response_time =
unsafe { AVG_RESPONSE_TIME_MICROS.load(Ordering::SeqCst) };
if saved_avg_response_time == NOT_SET_VALUE {
unsafe {
AVG_RESPONSE_TIME_MICROS.store(elapsed_ms, Ordering::SeqCst);
};
} else {
let new_avg_response_time = (saved_avg_response_time + elapsed_ms) / 2;
unsafe {
AVG_RESPONSE_TIME_MICROS
.store(new_avg_response_time, Ordering::SeqCst);
};
}
}
}
pub fn get_avg_response_time_micros() -> String {
let avg_response_time_micros =
unsafe { AVG_RESPONSE_TIME_MICROS.load(Ordering::SeqCst) };
if avg_response_time_micros == NOT_SET_VALUE {
"Not set.".to_string()
} else {
let fps = 1_000_000 / avg_response_time_micros;
format!("{avg_response_time_micros} μs, {fps} fps")
}
}
}
pub mod is_vscode_term_global_static {
use super::*;
pub static mut IS_VSCODE_TERM: AtomicI64 = AtomicI64::new(NOT_SET_VALUE);
fn detect_whether_is_vscode_term_from_env() -> VSCodeTerm {
let env_key = "TERM_PROGRAM";
let env_value = match std::env::var(env_key) {
Ok(value) => value == "vscode",
_ => false,
};
match env_value {
true => VSCodeTerm::Yes,
false => VSCodeTerm::No,
}
}
#[derive(Debug, Copy, Clone)]
pub enum VSCodeTerm {
Yes,
No,
}
impl From<i64> for VSCodeTerm {
fn from(value: i64) -> Self {
match value {
0 => VSCodeTerm::No,
1 => VSCodeTerm::Yes,
_ => VSCodeTerm::No,
}
}
}
impl From<VSCodeTerm> for i64 {
fn from(value: VSCodeTerm) -> Self {
match value {
VSCodeTerm::No => 0,
VSCodeTerm::Yes => 1,
}
}
}
pub fn get_is_vscode_term() -> VSCodeTerm {
let existing_value = unsafe { IS_VSCODE_TERM.load(Ordering::SeqCst) };
match existing_value == NOT_SET_VALUE {
true => {
let vscode_term = detect_whether_is_vscode_term_from_env();
unsafe {
IS_VSCODE_TERM.store(i64::from(vscode_term), Ordering::SeqCst);
}
vscode_term
}
false => VSCodeTerm::from(existing_value),
}
}
}