solverforge_scoring/stream/
balance_stream.rs1use std::hash::Hash;
8use std::marker::PhantomData;
9
10use solverforge_core::score::Score;
11use solverforge_core::{ConstraintRef, ImpactType};
12
13use super::collection_extract::CollectionExtract;
14use super::filter::UniFilter;
15use super::weighting_support::fixed_weight_is_hard;
16use crate::constraint::balance::BalanceConstraint;
17
18pub struct BalanceConstraintStream<S, A, K, E, F, KF, Sc>
66where
67 Sc: Score,
68{
69 extractor: E,
70 filter: F,
71 key_fn: KF,
72 _phantom: PhantomData<(fn() -> S, fn() -> A, fn() -> K, fn() -> Sc)>,
73}
74
75impl<S, A, K, E, F, KF, Sc> BalanceConstraintStream<S, A, K, E, F, KF, Sc>
76where
77 S: Send + Sync + 'static,
78 A: Clone + Send + Sync + 'static,
79 K: Clone + Eq + Hash + Send + Sync + 'static,
80 E: CollectionExtract<S, Item = A>,
81 F: UniFilter<S, A>,
82 KF: Fn(&A) -> Option<K> + Send + Sync,
83 Sc: Score + 'static,
84{
85 fn into_builder(
86 self,
87 impact_type: ImpactType,
88 base_score: Sc,
89 ) -> BalanceConstraintBuilder<S, A, K, E, F, KF, Sc> {
90 BalanceConstraintBuilder {
91 extractor: self.extractor,
92 filter: self.filter,
93 key_fn: self.key_fn,
94 impact_type,
95 base_score,
96 is_hard: fixed_weight_is_hard(base_score),
97 _phantom: PhantomData,
98 }
99 }
100
101 pub(crate) fn new(extractor: E, filter: F, key_fn: KF) -> Self {
103 Self {
104 extractor,
105 filter,
106 key_fn,
107 _phantom: PhantomData,
108 }
109 }
110
111 pub fn penalize(self, base_score: Sc) -> BalanceConstraintBuilder<S, A, K, E, F, KF, Sc> {
116 self.into_builder(ImpactType::Penalty, base_score)
117 }
118
119 pub fn reward(self, base_score: Sc) -> BalanceConstraintBuilder<S, A, K, E, F, KF, Sc> {
124 self.into_builder(ImpactType::Reward, base_score)
125 }
126}
127
128impl<S, A, K, E, F, KF, Sc: Score> std::fmt::Debug
129 for BalanceConstraintStream<S, A, K, E, F, KF, Sc>
130{
131 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
132 f.debug_struct("BalanceConstraintStream").finish()
133 }
134}
135
136pub struct BalanceConstraintBuilder<S, A, K, E, F, KF, Sc>
138where
139 Sc: Score,
140{
141 extractor: E,
142 filter: F,
143 key_fn: KF,
144 impact_type: ImpactType,
145 base_score: Sc,
146 is_hard: bool,
147 _phantom: PhantomData<(fn() -> S, fn() -> A, fn() -> K)>,
148}
149
150impl<S, A, K, E, F, KF, Sc> BalanceConstraintBuilder<S, A, K, E, F, KF, Sc>
151where
152 S: Send + Sync + 'static,
153 A: Clone + Send + Sync + 'static,
154 K: Clone + Eq + Hash + Send + Sync + 'static,
155 E: CollectionExtract<S, Item = A>,
156 F: UniFilter<S, A>,
157 KF: Fn(&A) -> Option<K> + Send + Sync,
158 Sc: Score + 'static,
159{
160 pub fn named(self, name: &str) -> BalanceConstraint<S, A, K, E, F, KF, Sc> {
161 BalanceConstraint::new(
162 ConstraintRef::new("", name),
163 self.impact_type,
164 self.extractor,
165 self.filter,
166 self.key_fn,
167 self.base_score,
168 self.is_hard,
169 )
170 }
171
172 }
174
175impl<S, A, K, E, F, KF, Sc: Score> std::fmt::Debug
176 for BalanceConstraintBuilder<S, A, K, E, F, KF, Sc>
177{
178 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
179 f.debug_struct("BalanceConstraintBuilder")
180 .field("impact_type", &self.impact_type)
181 .finish()
182 }
183}