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