use crate::gui::optics::crystal_optics::{
custom_material_specific_gravity_from_rows, gem_material_from_row,
};
use indicatrix::optics::materials::GemMaterial;
#[must_use]
pub(super) fn initial_custom_materials_and_specific_gravity(
rows: &[indicatrix_vault::model::material::CustomMaterialRow],
) -> (Vec<GemMaterial>, Vec<(String, f64)>) {
let materials = rows.iter().map(gem_material_from_row).collect();
let specific_gravity = custom_material_specific_gravity_from_rows(rows);
(materials, specific_gravity)
}
#[cfg(test)]
mod tests {
use super::initial_custom_materials_and_specific_gravity;
use indicatrix_vault::model::material::CustomMaterialRow;
fn custom_row(name: &str, specific_gravity: Option<f32>) -> CustomMaterialRow {
CustomMaterialRow {
name: name.to_string(),
refractive_index: 1.7,
dispersion: 0.02,
birefringence: 0.0,
absorption_rgb: [0.0, 0.0, 0.0],
crystal_system: None,
optical_character: None,
biaxial_delta_beta_alpha: None,
per_axis_dispersion_json: None,
specific_gravity,
color_recipe_json: None,
dispersion_model_json: None,
absorption_bands_json: None,
}
}
#[test]
fn startup_helper_populates_both_lists_from_one_row_read() {
let rows = [
custom_row("My Garnet", Some(3.90)),
custom_row("Custom Diamond", None),
];
let (materials, specific_gravity) = initial_custom_materials_and_specific_gravity(&rows);
assert_eq!(materials.len(), 2, "every row becomes a GemMaterial");
assert!(materials.iter().any(|m| m.name == "My Garnet"));
assert!(materials.iter().any(|m| m.name == "Custom Diamond"));
assert_eq!(
specific_gravity.len(),
1,
"only the row with a recorded SG contributes an entry, and a row \
with none is skipped rather than showing up as a spurious Some(0.0)"
);
assert_eq!(specific_gravity[0].0, "My Garnet");
assert!((specific_gravity[0].1 - 3.90_f64).abs() < 1e-6);
}
#[test]
fn startup_helper_is_empty_for_no_custom_materials() {
let (materials, specific_gravity) = initial_custom_materials_and_specific_gravity(&[]);
assert_eq!(materials.len(), 0);
assert_eq!(specific_gravity.len(), 0);
}
}