use crate::float::Float;
use crate::value::NormalizedContainer;
use core::marker::PhantomData;
pub struct ScoreSet<T: Float, Members> {
pub(crate) members: Members,
_phantom: PhantomData<T>,
}
impl<T: Float, Members> ScoreSet<T, Members>
where
Members: crate::Members<T>,
{
pub fn normalize(raw: Members::Raw) -> Result<Self, &'static str> {
let raw_weights = Members::extract_raw_weights(&raw);
let sum: T = raw_weights.iter().fold(T::zero(), |a, &b| a + b);
let normalized: Vec<T> = raw_weights.iter().map(|&w| w / sum).collect();
let container = NormalizedContainer::witness(normalized)?;
Ok(ScoreSet {
members: Members::from_raw_with_weights(raw, &container),
_phantom: PhantomData,
})
}
#[inline]
pub fn score(&self) -> ScoreStage<'_, T, Members> {
ScoreStage {
members: &self.members,
_phantom: PhantomData,
}
}
}
pub struct ScoreStage<'a, T: Float, Members> {
members: &'a Members,
_phantom: PhantomData<T>,
}
impl<'a, T: Float, Members> ScoreStage<'a, T, Members> {
#[inline]
pub fn by<F, R>(self, f: F) -> R
where
F: FnOnce(&Members) -> R,
{
f(self.members)
}
}
#[cfg(test)]
mod tests_for_set;