Skip to main content

score_set/
dyn_score_set.rs

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