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}