Skip to main content

score_set/
dyn_score_set.rs

1use std::marker::PhantomData;
2
3use crate::traits::{EvalF32, EvalF64};
4
5/// A dynamic `f64` score set that sums a list of evaluators.
6pub struct DynScoreSet64<Ctx: ?Sized> {
7    metrics: Box<[Box<dyn EvalF64<Ctx> + 'static>]>,
8}
9
10impl<Ctx: ?Sized> DynScoreSet64<Ctx> {
11    /// Creates a builder for `DynScoreSet64`.
12    pub fn builder() -> DynScoreSet64Builder<Ctx> {
13        DynScoreSet64Builder::default()
14    }
15
16    /// Returns the number of stored metrics.
17    pub fn len(&self) -> usize {
18        self.metrics.len()
19    }
20
21    /// Returns `true` when no metrics are stored.
22    pub fn is_empty(&self) -> bool {
23        self.metrics.is_empty()
24    }
25}
26
27impl<Ctx: ?Sized> EvalF64<Ctx> for DynScoreSet64<Ctx> {
28    #[inline]
29    fn eval(&self, ctx: &Ctx) -> f64 {
30        self.metrics
31            .iter()
32            .fold(0.0, |sum, metric| sum + metric.eval(ctx))
33    }
34}
35
36/// Builds a `DynScoreSet64`.
37pub struct DynScoreSet64Builder<Ctx: ?Sized> {
38    metrics: Vec<Box<dyn EvalF64<Ctx> + 'static>>,
39    marker: PhantomData<fn(&Ctx)>,
40}
41
42impl<Ctx: ?Sized> Default for DynScoreSet64Builder<Ctx> {
43    fn default() -> Self {
44        Self {
45            metrics: Vec::new(),
46            marker: PhantomData,
47        }
48    }
49}
50
51impl<Ctx: ?Sized> DynScoreSet64Builder<Ctx> {
52    /// Appends one evaluator to the score set being built.
53    pub fn push<E>(&mut self, eval: E)
54    where
55        E: EvalF64<Ctx> + 'static,
56    {
57        self.metrics.push(Box::new(eval));
58    }
59
60    /// Appends one evaluator and returns the builder.
61    pub fn append<E>(mut self, eval: E) -> Self
62    where
63        E: EvalF64<Ctx> + 'static,
64    {
65        self.push(eval);
66        self
67    }
68
69    /// Finalizes the builder into a `DynScoreSet64`.
70    pub fn build(self) -> DynScoreSet64<Ctx> {
71        DynScoreSet64 {
72            metrics: self.metrics.into_boxed_slice(),
73        }
74    }
75}
76
77/// A dynamic `f32` score set that sums a list of evaluators.
78pub struct DynScoreSet32<Ctx: ?Sized> {
79    metrics: Box<[Box<dyn EvalF32<Ctx> + 'static>]>,
80}
81
82impl<Ctx: ?Sized> DynScoreSet32<Ctx> {
83    /// Creates a builder for `DynScoreSet32`.
84    pub fn builder() -> DynScoreSet32Builder<Ctx> {
85        DynScoreSet32Builder::default()
86    }
87
88    /// Returns the number of stored metrics.
89    pub fn len(&self) -> usize {
90        self.metrics.len()
91    }
92
93    /// Returns `true` when no metrics are stored.
94    pub fn is_empty(&self) -> bool {
95        self.metrics.is_empty()
96    }
97}
98
99impl<Ctx: ?Sized> EvalF32<Ctx> for DynScoreSet32<Ctx> {
100    #[inline]
101    fn eval(&self, ctx: &Ctx) -> f32 {
102        self.metrics
103            .iter()
104            .fold(0.0, |sum, metric| sum + metric.eval(ctx))
105    }
106}
107
108/// Builds a `DynScoreSet32`.
109pub struct DynScoreSet32Builder<Ctx: ?Sized> {
110    metrics: Vec<Box<dyn EvalF32<Ctx> + 'static>>,
111    marker: PhantomData<fn(&Ctx)>,
112}
113
114impl<Ctx: ?Sized> Default for DynScoreSet32Builder<Ctx> {
115    fn default() -> Self {
116        Self {
117            metrics: Vec::new(),
118            marker: PhantomData,
119        }
120    }
121}
122
123impl<Ctx: ?Sized> DynScoreSet32Builder<Ctx> {
124    /// Appends one evaluator to the score set being built.
125    pub fn push<E>(&mut self, eval: E)
126    where
127        E: EvalF32<Ctx> + 'static,
128    {
129        self.metrics.push(Box::new(eval));
130    }
131
132    /// Appends one evaluator and returns the builder.
133    pub fn append<E>(mut self, eval: E) -> Self
134    where
135        E: EvalF32<Ctx> + 'static,
136    {
137        self.push(eval);
138        self
139    }
140
141    /// Finalizes the builder into a `DynScoreSet32`.
142    pub fn build(self) -> DynScoreSet32<Ctx> {
143        DynScoreSet32 {
144            metrics: self.metrics.into_boxed_slice(),
145        }
146    }
147}