pub trait RareProperties: PartialEq + Default + 'static {
const EMPTY: &'static Self;
}
pub fn rare<T: RareProperties>(slot: &Option<Box<T>>) -> &T {
slot.as_deref().unwrap_or(T::EMPTY)
}
pub fn set_rare<T: RareProperties>(slot: &mut Option<Box<T>>, properties: T) {
if properties == *T::EMPTY {
*slot = None;
} else if let Some(held) = slot {
**held = properties;
} else {
*slot = Some(Box::new(properties));
}
}
pub fn update_rare<T: RareProperties>(slot: &mut Option<Box<T>>, update: impl FnOnce(&mut T)) {
let mut properties = slot.as_deref_mut().map(std::mem::take).unwrap_or_default();
update(&mut properties);
set_rare(slot, properties);
}