Skip to main content

score_set/
member.rs

1use crate::float::Float;
2use crate::value::{GtZero, NormalizedContainer, NormalizedWeight, Value01};
3use witnessed::Witnessed;
4
5// ---------------------------------------------------------------------------
6// Members trait — maps raw tuple to normalized tuple
7// ---------------------------------------------------------------------------
8
9/// Trait that maps raw member tuples to normalized member tuples.
10#[doc(hidden)]
11pub trait Members<T: Float>: Sized {
12    /// The raw (pre-normalization) member tuple.
13    type Raw;
14
15    /// Extract raw weight values from the raw member tuple.
16    fn extract_raw_weights(raw: &Self::Raw) -> Vec<T>;
17
18    /// Build the normalized member tuple from raw members, the unsorted
19    /// normalized-weight slice (insertion order), and a **sorted** validated
20    /// normalized container.
21    ///
22    /// `normalized[idx]` supplies the weight value for member `idx` in insertion
23    /// order; the value is then validated against the sorted `container` via
24    /// [`NormalizedWeight::from_normalized_container`].
25    fn from_raw_with_weights(
26        raw: Self::Raw,
27        normalized: &[T],
28        container: &Witnessed<Vec<T>, NormalizedContainer>,
29    ) -> Self;
30}
31
32// ---------------------------------------------------------------------------
33// RawMember — weight + metric before normalization
34// ---------------------------------------------------------------------------
35
36/// A raw member: a strictly-positive weight paired with a metric.
37#[doc(hidden)]
38#[derive(Debug, Clone, Copy)]
39pub struct RawMember<T: Float, M> {
40    pub(crate) weight: Witnessed<T, GtZero>,
41    pub(crate) metric: M,
42}
43
44impl<T: Float, M> RawMember<T, M> {
45    /// Access the raw weight value.
46    pub fn weight(&self) -> T {
47        *self.weight
48    }
49
50    /// Access the metric.
51    pub fn metric(&self) -> &M {
52        &self.metric
53    }
54}
55
56/// Construct a `RawMember`, validating that `weight` is strictly positive.
57#[doc(hidden)]
58#[inline]
59pub fn raw_member<T: Float, M>(weight: T, metric: M) -> Result<RawMember<T, M>, &'static str> {
60    let w = GtZero::witness(weight)?;
61    Ok(RawMember { weight: w, metric })
62}
63
64// ---------------------------------------------------------------------------
65// Member — normalized weight + metric
66// ---------------------------------------------------------------------------
67
68/// A member of a [`MetricSet`](crate::MetricSet): a normalized weight paired
69/// with its metric.
70#[derive(Debug, Clone, Copy)]
71pub struct Member<T: Float, M> {
72    /// The normalized weight.
73    pub weight: Witnessed<T, NormalizedWeight>,
74    /// The metric or operator.
75    pub metric: M,
76}
77
78impl<T: Float, M> Member<T, M> {
79    /// Compute the contribution of a metric score.
80    ///
81    /// `contribute(score) = score × normalized_weight`
82    #[inline]
83    pub fn contribute(&self, value: Witnessed<T, Value01>) -> T {
84        value.into_inner() * self.weight.into_inner()
85    }
86
87    /// Return a reference to the metric.
88    #[inline]
89    pub fn metric(&self) -> &M {
90        &self.metric
91    }
92}
93
94#[cfg(test)]
95mod tests_for_member;