blob: 0962f1c97b3616e6fbe249b4d3e585319bed95ca [file] [log] [blame]
use figment::providers::{Format, Json, Toml};
use figment::Figment;
use serde_json::Value;
use std::error;
use std::path::PathBuf;
use vergen::EmitBuilder;
const JSON_CONFIG_FILENAME: &str = "server.json";
const TOML_CONFIG_FILENAME: &str = "server.toml";
fn main() -> Result<(), Box<dyn error::Error>> {
if option_env!("IGGY_CI_BUILD") == Some("true") {
EmitBuilder::builder()
.all_build()
.all_cargo()
.all_git()
.all_rustc()
.emit()?;
let workspace_root = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("..");
println!(
"cargo:rerun-if-changed={}",
workspace_root
.join("configs")
.canonicalize()
.unwrap()
.display()
);
let json_config_path = workspace_root
.clone()
.join("configs")
.join(JSON_CONFIG_FILENAME);
let toml_config_path = workspace_root.join("configs").join(TOML_CONFIG_FILENAME);
let json_config: Value = match Figment::new().merge(Json::file(json_config_path)).extract()
{
Ok(config) => config,
Err(e) => panic!("Failed to load {JSON_CONFIG_FILENAME}: {e}"),
};
let toml_config: Value = match Figment::new().merge(Toml::file(toml_config_path)).extract()
{
Ok(config) => config,
Err(e) => panic!("Failed to load {TOML_CONFIG_FILENAME}: {e}"),
};
compare_configs(&json_config, &toml_config, "");
} else {
println!("cargo:info=Skipping build script because CI environment variable IGGY_CI_BUILD is not set to 'true'");
}
Ok(())
}
fn compare_configs(json_value: &Value, toml_value: &Value, path: &str) {
match (json_value, toml_value) {
(Value::Object(json_map), Value::Object(toml_map)) => {
for (key, j_val) in json_map {
let new_path = if path.is_empty() {
key.clone()
} else {
format!("{} -> {}", path, key)
};
match toml_map.get(key) {
Some(t_val) => compare_configs(j_val, t_val, &new_path),
None => panic!(
"Key '{key}' found in {JSON_CONFIG_FILENAME} but not {TOML_CONFIG_FILENAME} \
at path: {path}"
),
}
}
for key in toml_map.keys() {
if !json_map.contains_key(key) {
panic!(
"Key '{key}' found in {TOML_CONFIG_FILENAME} but not in {JSON_CONFIG_FILENAME} \
at path: {path}",
);
}
}
}
(Value::Array(j_arr), Value::Array(t_arr)) => {
if j_arr.len() != t_arr.len() {
panic!(
"Array length differs at path '{path}': {JSON_CONFIG_FILENAME} has {} elements, \
{TOML_CONFIG_FILENAME} has {} elements",
j_arr.len(),
t_arr.len()
);
} else {
for (i, (j_val, t_val)) in j_arr.iter().zip(t_arr).enumerate() {
let new_path = format!("{}[{}]", path, i);
compare_configs(j_val, t_val, &new_path);
}
}
}
_ => {
if json_value != toml_value {
panic!(
"Difference in {JSON_CONFIG_FILENAME} vs {TOML_CONFIG_FILENAME} \
found at '{path}': JSON value: {:?}, TOML value: {:?}",
json_value, toml_value
);
}
}
}
}