1use crate::float::Float;
2use crate::value::NormalizedContainer;
3use core::marker::PhantomData;
4
5pub struct ScoreSet<T: Float, Members> {
15 pub(crate) members: Members,
16 _phantom: PhantomData<T>,
17}
18
19impl<T: Float, Members> ScoreSet<T, Members>
20where
21 Members: crate::Members<T>,
22{
23 pub fn normalize(raw: Members::Raw) -> Result<Self, &'static str> {
25 let raw_weights = Members::extract_raw_weights(&raw);
26 let sum: T = raw_weights.iter().fold(T::zero(), |a, &b| a + b);
27 let normalized: Vec<T> = raw_weights.iter().map(|&w| w / sum).collect();
28 let container = NormalizedContainer::witness(normalized)?;
29 Ok(ScoreSet {
30 members: Members::from_raw_with_weights(raw, &container),
31 _phantom: PhantomData,
32 })
33 }
34
35 #[inline]
37 pub fn score(&self) -> ScoreStage<'_, T, Members> {
38 ScoreStage {
39 members: &self.members,
40 _phantom: PhantomData,
41 }
42 }
43}
44
45pub struct ScoreStage<'a, T: Float, Members> {
54 members: &'a Members,
55 _phantom: PhantomData<T>,
56}
57
58impl<'a, T: Float, Members> ScoreStage<'a, T, Members> {
59 #[inline]
61 pub fn by<F, R>(self, f: F) -> R
62 where
63 F: FnOnce(&Members) -> R,
64 {
65 f(self.members)
66 }
67}
68
69#[cfg(test)]
70mod tests_for_set;