use crate::imports::*;
pub mod serde_api;
pub use serde_api::*;
pub trait Idx {
fn idx(self) -> usize;
}
#[duplicate_item(Self; [u8]; [u16])]
impl Idx for Self {
fn idx(self) -> usize {
self.into()
}
}
impl Idx for u32 {
fn idx(self) -> usize {
self.try_into().unwrap()
}
}
impl Idx for Option<NonZeroU16> {
fn idx(self) -> usize {
self.map(u16::from).unwrap_or(0) as usize
}
}
pub trait TryFromIdx<T> {
type Error;
fn try_from_idx(&self) -> Result<Option<T>, Self::Error>;
}
impl<T> TryFromIdx<T> for usize
where
T: TryFrom<NonZeroUsize>,
{
type Error = <T as TryFrom<NonZeroUsize>>::Error;
fn try_from_idx(&self) -> Result<Option<T>, Self::Error> {
NonZeroUsize::new(*self).map_or(
Ok(None),
|val| {
T::try_from(val)
.map(Some)
},
)
}
}
pub trait Linspace {
fn linspace(start: f64, stop: f64, n_elements: usize) -> Vec<f64> {
let n_steps = n_elements - 1;
let step_size = (stop - start) / n_steps as f64;
let v_norm: Vec<f64> = (0..=n_steps)
.collect::<Vec<usize>>()
.iter()
.map(|x| *x as f64)
.collect();
let v = v_norm.iter().map(|x| (x * step_size) + start).collect();
v
}
}
impl Linspace for Vec<f64> {}
pub trait EqDefault: Default + PartialEq {
fn eq_default(&self) -> bool {
*self == Self::default()
}
}
impl<T: Default + PartialEq> EqDefault for T {}
#[derive(Default, Deserialize, Serialize, Debug, Clone, PartialEq)]
pub enum MassSideEffect {
#[default]
None,
Extensive,
Intensive,
}
impl TryFrom<String> for MassSideEffect {
type Error = anyhow::Error;
fn try_from(value: String) -> anyhow::Result<MassSideEffect> {
let mass_side_effect = match value.as_str() {
"None" => Self::None,
"Extensive" => Self::Extensive,
"Intensive" => Self::Intensive,
_ => {
bail!(format!(
"`MassSideEffect` must be 'Intensive', 'Extensive', or 'None'. "
))
}
};
Ok(mass_side_effect)
}
}
pub trait Mass {
fn mass(&self) -> anyhow::Result<Option<si::Mass>>;
fn set_mass(
&mut self,
new_mass: Option<si::Mass>,
side_effect: MassSideEffect,
) -> anyhow::Result<()>;
fn derived_mass(&self) -> anyhow::Result<Option<si::Mass>>;
fn expunge_mass_fields(&mut self);
fn set_mass_specific_property(&mut self) -> anyhow::Result<()> {
Ok(())
}
}
pub trait StateMethods: SetCumulative + SaveState + Step + CheckAndResetState {}
pub trait SetCumulative {
fn set_cumulative<F: Fn() -> String>(&mut self, dt: si::Time, loc: F) -> anyhow::Result<()>;
}
pub trait SaveState {
fn save_state<F: Fn() -> String>(&mut self, loc: F) -> anyhow::Result<()>;
}
pub trait Step {
fn step<F: Fn() -> String>(&mut self, loc: F) -> anyhow::Result<()>;
}
pub trait HistoryMethods: SaveState {
fn set_save_interval(&mut self, save_interval: Option<usize>) -> anyhow::Result<()>;
fn save_interval(&self) -> anyhow::Result<Option<usize>>;
fn clear(&mut self);
}