conformal_component/parameters/utils/
either.rs1use itertools::Either;
2
3use crate::parameters::{NumericBufferState, PiecewiseLinearCurve, PiecewiseLinearCurvePoint};
4
5pub fn left_numeric_buffer<
11 A: Iterator<Item = PiecewiseLinearCurvePoint> + Clone,
12 B: Iterator<Item = PiecewiseLinearCurvePoint> + Clone,
13>(
14 state: NumericBufferState<A>,
15) -> NumericBufferState<Either<A, B>> {
16 match state {
17 NumericBufferState::Constant(value) => NumericBufferState::Constant(value),
18 NumericBufferState::PiecewiseLinear(curve) => {
19 let buffer_size = curve.buffer_size();
20 NumericBufferState::PiecewiseLinear(unsafe {
22 PiecewiseLinearCurve::from_parts_unchecked(
23 Either::Left(curve.into_iter()),
24 buffer_size,
25 )
26 })
27 }
28 }
29}
30
31pub fn right_numeric_buffer<
37 A: Iterator<Item = PiecewiseLinearCurvePoint> + Clone,
38 B: Iterator<Item = PiecewiseLinearCurvePoint> + Clone,
39>(
40 state: NumericBufferState<B>,
41) -> NumericBufferState<Either<A, B>> {
42 match state {
43 NumericBufferState::Constant(value) => NumericBufferState::Constant(value),
44 NumericBufferState::PiecewiseLinear(curve) => {
45 let buffer_size = curve.buffer_size();
46 NumericBufferState::PiecewiseLinear(unsafe {
47 PiecewiseLinearCurve::from_parts_unchecked(
49 Either::Right(curve.into_iter()),
50 buffer_size,
51 )
52 })
53 }
54 }
55}
56
57#[cfg(test)]
58mod tests {
59 use super::*;
60 use crate::parameters::{PiecewiseLinearCurve, PiecewiseLinearCurvePoint};
61
62 type Iter = std::vec::IntoIter<PiecewiseLinearCurvePoint>;
63
64 fn make_curve() -> PiecewiseLinearCurve<Iter> {
65 let curve = PiecewiseLinearCurve::new(
66 vec![
67 PiecewiseLinearCurvePoint {
68 sample_offset: 0,
69 value: 0.0,
70 },
71 PiecewiseLinearCurvePoint {
72 sample_offset: 50,
73 value: 1.0,
74 },
75 ],
76 128,
77 0.0..=1.0,
78 )
79 .unwrap();
80 let buffer_size = curve.buffer_size();
81 unsafe { PiecewiseLinearCurve::from_parts_unchecked(curve.into_iter(), buffer_size) }
82 }
83
84 #[test]
85 fn left_constant_preserves_value() {
86 let state: NumericBufferState<Iter> = NumericBufferState::Constant(0.5);
87 let result = left_numeric_buffer::<_, Iter>(state);
88 assert_eq!(result.value_at_start_of_buffer(), 0.5);
89 }
90
91 #[test]
92 fn right_constant_preserves_value() {
93 let state: NumericBufferState<Iter> = NumericBufferState::Constant(0.75);
94 let result = right_numeric_buffer::<Iter, _>(state);
95 assert_eq!(result.value_at_start_of_buffer(), 0.75);
96 }
97
98 #[test]
99 fn left_piecewise_linear_preserves_points() {
100 let state = NumericBufferState::PiecewiseLinear(make_curve());
101 let result = left_numeric_buffer::<_, Iter>(state);
102 match result {
103 NumericBufferState::PiecewiseLinear(curve) => {
104 assert_eq!(curve.buffer_size(), 128);
105 let points: Vec<_> = curve.into_iter().collect();
106 assert_eq!(points.len(), 2);
107 assert_eq!(points[0].value, 0.0);
108 assert_eq!(points[1].value, 1.0);
109 }
110 _ => panic!("expected PiecewiseLinear"),
111 }
112 }
113
114 #[test]
115 fn right_piecewise_linear_preserves_points() {
116 let state = NumericBufferState::PiecewiseLinear(make_curve());
117 let result = right_numeric_buffer::<Iter, _>(state);
118 match result {
119 NumericBufferState::PiecewiseLinear(curve) => {
120 assert_eq!(curve.buffer_size(), 128);
121 let points: Vec<_> = curve.into_iter().collect();
122 assert_eq!(points.len(), 2);
123 assert_eq!(points[0].value, 0.0);
124 assert_eq!(points[1].value, 1.0);
125 }
126 _ => panic!("expected PiecewiseLinear"),
127 }
128 }
129}