Skip to main content

score_set/
macros.rs

1/// Declare a fixed set of `weight => metric` pairs (Layer 1).
2///
3/// Each weight is validated > 0 via [`GtZero`](crate::GtZero). The macro
4/// normalizes weights and returns a [`FixedScoreSet`](crate::FixedScoreSet)
5/// directly.
6///
7/// # Example
8///
9/// ```ignore
10/// let gc  = metric("gc") .measure().by(...).map01().by(...);
11/// let len = metric("len").measure().by(...).map01().by(...);
12///
13/// let ms = fixed_score_set! {
14///     2.0 => gc,
15///     3.0 => len,
16/// }?;
17/// ```
18#[macro_export]
19macro_rules! fixed_score_set {
20    ($($weight:expr => $metric:expr),+ $(,)?) => {
21        (|| -> Result<_, &'static str> {
22            $crate::FixedScoreSet::normalize((
23                $($crate::raw_member($weight, $metric)?,)+
24            ))
25        })()
26    };
27}
28
29/// Declare a finite set of `weight => metric` pairs (Layer 2).
30///
31/// Metrics are auto-wrapped in an anonymous zero-vtable enum (no explicit
32/// [`finite_metric!`](crate::finite_metric!) declaration needed). For named
33/// variants or a `Custom` escape hatch, use
34/// [`finite_metric!`](crate::finite_metric!) directly.
35///
36/// # Example
37///
38/// ```ignore
39/// let gc  = metric("gc") .measure().by(...).map01().by(...);
40/// let len = metric("len").measure().by(...).map01().by(...);
41///
42/// let set = finite_score_set! {
43///     2.0 => gc,
44///     3.0 => len,
45/// }?;
46///
47/// let total = set.sum(&input);
48/// ```
49#[macro_export]
50macro_rules! finite_score_set {
51    // empty
52    () => {
53        $crate::FiniteScoreSet::normalize(vec![])
54    };
55    // 1+ members — tuples into trait dispatch, symmetric with `fixed_score_set!` / `Members`
56    ($($weight:expr => $metric:expr),+ $(,)?) => {
57        $crate::FiniteScoreSet::normalize(
58            $crate::into_finite_entries(
59                ($($metric,)+),
60                &[$($weight),+],
61            )
62        )
63    };
64}
65
66/// Declare a dynamic set of `weight => metric` pairs (Layer 3).
67///
68/// Metrics are auto-boxed via [`.boxed()`](crate::Metric::boxed) — no manual
69/// boxing needed. Weights are normalized and a
70/// [`DynamicScoreSet`](crate::DynamicScoreSet) is returned.
71///
72/// # Example
73///
74/// ```ignore
75/// let gc  = metric("gc") .measure().by(...).map01().by(...);
76/// let len = metric("len").measure().by(...).map01().by(...);
77///
78/// let set = dynamic_score_set! {
79///     2.0 => gc,
80///     3.0 => len,
81/// }?;
82///
83/// let total = set.sum(&input);
84/// ```
85#[macro_export]
86macro_rules! dynamic_score_set {
87    () => {
88        $crate::DynamicScoreSet::normalize(vec![])
89    };
90    ($($weight:expr => $metric:expr),+ $(,)?) => {
91        $crate::DynamicScoreSet::normalize(vec![
92            $(($weight, $metric.boxed())),+
93        ])
94    };
95}