use indicatrix_cut_core::MaterialSelection;
pub(in crate::gui::editor) const RI_PRESERVE_TOLERANCE: f64 = 0.01;
#[must_use]
pub(in crate::gui::editor) fn ri_override_to_preserve(name: &str, original_ri: f64) -> Option<f64> {
let built_in_ri = indicatrix_cut_core::built_in_refractive_index(name)?;
((built_in_ri - original_ri).abs() > RI_PRESERVE_TOLERANCE).then_some(original_ri)
}
pub(in crate::gui::editor) fn material_selection_for_accepted_suggestion(
name: &str,
schedule_ri: f64,
current: &MaterialSelection,
) -> MaterialSelection {
MaterialSelection {
name: Some(name.to_string()),
specific_gravity_override: current.specific_gravity_override,
refractive_index_override: ri_override_to_preserve(name, schedule_ri),
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn accepted_suggestion_sets_no_override_when_the_built_in_ri_is_within_tolerance() {
let quartz_ri = indicatrix_cut_core::built_in_refractive_index("Quartz").unwrap();
let current = MaterialSelection::none();
let selection = material_selection_for_accepted_suggestion("Quartz", quartz_ri, ¤t);
assert_eq!(selection.name.as_deref(), Some("Quartz"));
assert_eq!(selection.refractive_index_override, None);
}
#[test]
fn accepted_suggestion_pins_the_schedule_ri_when_the_built_in_ri_differs_by_more_than_the_tolerance()
{
let quartz_ri = indicatrix_cut_core::built_in_refractive_index("Quartz").unwrap();
let schedule_ri = quartz_ri + 0.02;
let current = MaterialSelection::none();
let selection = material_selection_for_accepted_suggestion("Quartz", schedule_ri, ¤t);
assert_eq!(selection.refractive_index_override, Some(schedule_ri));
}
#[test]
fn accepted_suggestion_keeps_the_current_specific_gravity_override() {
let mut current = MaterialSelection::none();
current.specific_gravity_override = Some(3.9);
let selection = material_selection_for_accepted_suggestion("Diamond", 2.417, ¤t);
assert_eq!(selection.specific_gravity_override, Some(3.9));
}
#[test]
fn ri_override_to_preserve_pins_the_original_ri_when_the_built_in_drifts() {
let diamond_ri = indicatrix_cut_core::built_in_refractive_index("Diamond").unwrap();
let original_ri = 1.54;
assert!((diamond_ri - original_ri).abs() > RI_PRESERVE_TOLERANCE);
assert_eq!(
ri_override_to_preserve("Diamond", original_ri),
Some(original_ri)
);
}
#[test]
fn ri_override_to_preserve_does_nothing_when_already_close_enough() {
let diamond_ri = indicatrix_cut_core::built_in_refractive_index("Diamond").unwrap();
assert_eq!(ri_override_to_preserve("Diamond", diamond_ri), None);
}
#[test]
fn ri_override_to_preserve_does_nothing_for_a_non_built_in_name() {
assert_eq!(ri_override_to_preserve("Not A Real Material", 1.54), None);
}
}