use std::{
ops::Deref,
path::PathBuf,
sync::{Arc, RwLock},
time::Duration,
};
use ::serde::{Deserialize, Serialize};
use tower_lsp::lsp_types::Color;
mod serde;
static LSP_SETTINGS: RwLock<Settings> = RwLock::new(Settings::new());
#[derive(Debug, Serialize, Deserialize, PartialEq)]
#[serde(default)]
pub struct Settings {
#[serde(with = "serde")]
pub hit: Option<Color>,
#[serde(with = "serde")]
pub miss: Option<Color>,
#[serde(with = "humantime_serde")]
pub interval: Duration,
pub lcov_file: Option<Arc<PathBuf>>,
}
impl Default for Settings {
fn default() -> Self {
Self::new()
}
}
impl Settings {
pub const fn new() -> Self {
Self {
hit: Some(Color {
red: 0.0,
green: 1.0,
blue: 0.0,
alpha: 0.1,
}),
miss: Some(Color {
red: 1.0,
green: 0.0,
blue: 0.0,
alpha: 0.1,
}),
interval: Duration::from_secs(3),
lcov_file: None,
}
}
pub fn get() -> impl Deref<Target = Self> {
LSP_SETTINGS.read().unwrap()
}
pub fn set(settings: Settings) {
*LSP_SETTINGS.write().unwrap() = settings;
}
}
#[cfg(test)]
mod tests {
use std::{path::PathBuf, sync::Arc};
use super::Settings;
#[test]
fn serde() -> serde_json::Result<()> {
let settings: Settings = serde_json::from_str(
r#"{ "hit": null, "miss": "red", "interval": "20s", "lcov_file": "./lcov.info" }"#,
)?;
let settings: Settings = serde_json::from_str(serde_json::to_string(&settings)?.as_str())?;
assert_eq!(
settings.lcov_file,
Some(Arc::new(PathBuf::from("./lcov.info")))
);
assert_eq!(settings.interval, std::time::Duration::from_secs(20));
serde_json::from_str::<Settings>("{}")?;
Ok(())
}
}