des_sim/modeling/sampler/combinator/
map.rs1use crate::modeling::sampler::{DurationSampler, PendingDuration};
8use crate::primitive::time::SimTime;
9use rand::Rng;
10
11#[derive(Debug, Clone)]
13pub struct MapSampler<S, F>
14where
15 S: DurationSampler,
16 F: FnMut(&mut dyn Rng, SimTime, f64) -> f64,
17{
18 sampler: S,
19 f: F,
20}
21
22impl<S, F> DurationSampler for MapSampler<S, F>
23where
24 S: DurationSampler,
25 F: FnMut(&mut dyn Rng, SimTime, f64) -> f64,
26{
27 fn sample(&mut self, rng: &mut dyn Rng, current_tick: SimTime) -> PendingDuration {
28 let sampled = self.sampler.sample(rng, current_tick);
29
30 PendingDuration::new((self.f)(rng, current_tick, sampled.raw_value()))
31 }
32}
33
34impl<S, F> MapSampler<S, F>
35where
36 S: DurationSampler,
37 F: FnMut(&mut dyn Rng, SimTime, f64) -> f64,
38{
39 pub fn new(sampler: S, f: F) -> Self {
41 MapSampler { sampler, f }
42 }
43}
44
45#[cfg(test)]
46mod tests {
47 use super::*;
48 use crate::modeling::sampler::instance::ConstantSampler;
49 use rand::SeedableRng;
50 use rand::rngs::SmallRng;
51
52 #[test]
53 fn test_map_sampler_double_value() {
54 let mut rng = SmallRng::seed_from_u64(2);
55 let base_sampler = ConstantSampler::new(10.0);
56 let mut sampler = MapSampler::new(base_sampler, |_, _, value| value * 2.0);
57
58 let sample = sampler.sample(&mut rng, SimTime::from_ticks(0));
59 assert_eq!(sample.raw_value(), 20.0);
60 }
61
62 #[test]
63 fn test_map_sampler_add_offset() {
64 let mut rng = SmallRng::seed_from_u64(2);
65 let base_sampler = ConstantSampler::new(10.0);
66 let mut sampler = MapSampler::new(base_sampler, |_, _, value| value + 5.0);
67
68 let sample = sampler.sample(&mut rng, SimTime::from_ticks(0));
69 assert_eq!(sample.raw_value(), 15.0);
70 }
71
72 #[test]
73 fn test_map_sampler_negate_value() {
74 let mut rng = SmallRng::seed_from_u64(2);
75 let base_sampler = ConstantSampler::new(10.0);
76 let mut sampler = MapSampler::new(base_sampler, |_, _, value| -value);
77
78 let sample = sampler.sample(&mut rng, SimTime::from_ticks(0));
79 assert_eq!(sample.raw_value(), -10.0);
80 }
81}