use anyhow::anyhow;
use bevy::prelude::*;
use serde::{de::DeserializeOwned, Deserialize};
use super::JujutsuCli;
#[mutants::skip]
#[tracing::instrument(skip_all)]
pub fn plugin(app: &mut App) {
trace!("Initializing plugin...");
app.init_resource::<Config>();
trace!("Plugin initialized.");
}
#[allow(unused)]
#[derive(Debug, Deserialize)]
struct ConfigRoot {
#[serde(default = "default_table")]
jjj: Config,
}
#[mutants::skip]
fn default_table<De: DeserializeOwned>() -> De {
toml::de::from_str::<De>("").unwrap()
}
#[derive(Debug, Deserialize, PartialEq, Eq, Reflect, Resource)]
pub struct Config {
#[serde(default = "default_table")]
pub log: LogConfig,
#[serde(default = "default_table")]
pub splash: SplashConfig,
}
impl FromWorld for Config {
fn from_world(world: &mut World) -> Self {
let jj_cli = world.resource::<JujutsuCli>();
let config_toml = jj_cli.list_config().unwrap();
let root = toml::de::from_str::<ConfigRoot>(&config_toml)
.map_err(|e| anyhow!("Failed to parse config: {e}"))
.unwrap();
info!("{:?}", &root.jjj);
root.jjj
}
}
impl Config {
#[mutants::skip]
pub fn default() -> Self {
default_table()
}
}
#[derive(Debug, Deserialize, PartialEq, Eq, Reflect)]
pub struct LogConfig {
#[serde(default = "LogConfig::default_poll_interval_ms")]
pub poll_interval_ms: u64,
}
impl LogConfig {
#[mutants::skip]
fn default_poll_interval_ms() -> u64 {
1000
}
}
#[derive(Debug, Deserialize, PartialEq, Eq, Reflect)]
pub struct SplashConfig {
#[serde(default)]
pub skip: bool,
#[serde(default = "SplashConfig::default_total_duration_ms")]
pub total_duration_ms: u64,
#[serde(default = "SplashConfig::default_line_interval_ms")]
pub line_interval_ms: u64,
}
impl SplashConfig {
#[mutants::skip]
fn default_total_duration_ms() -> u64 {
1950
}
#[mutants::skip]
fn default_line_interval_ms() -> u64 {
150
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn loads_blank_config() {
let mut app = App::new();
app.insert_resource(JujutsuCli::mock(|_| Ok("".into())));
app.init_resource::<Config>();
assert_eq!(app.world().get_resource::<Config>(), Some(&default_table()));
}
#[test]
fn loads_populated_config() {
let mut app = App::new();
app.insert_resource(JujutsuCli::mock(|_| {
Ok(r#"
ui.editor = "hx"
jjj.log.poll_interval_ms = 123
jjj.splash.skip = true
jjj.splash.total_duration_ms = 4567
"#
.into())
}));
app.init_resource::<Config>();
assert_eq!(
app.world().get_resource::<Config>(),
Some(&Config {
log: LogConfig {
poll_interval_ms: 123,
..default_table()
},
splash: SplashConfig {
skip: true,
total_duration_ms: 4567,
..default_table()
},
..default_table()
})
);
}
}