style/values/animated/
lists.rs1pub mod by_computed_value {
11    use crate::values::{
12        animated::{Animate, Procedure},
13        distance::{ComputeSquaredDistance, SquaredDistance},
14    };
15    use std::iter::FromIterator;
16
17    #[allow(missing_docs)]
18    pub fn animate<T, C>(left: &[T], right: &[T], procedure: Procedure) -> Result<C, ()>
19    where
20        T: Animate,
21        C: FromIterator<T>,
22    {
23        if left.len() != right.len() {
24            return Err(());
25        }
26        left.iter()
27            .zip(right.iter())
28            .map(|(left, right)| left.animate(right, procedure))
29            .collect()
30    }
31
32    #[allow(missing_docs)]
33    pub fn squared_distance<T>(left: &[T], right: &[T]) -> Result<SquaredDistance, ()>
34    where
35        T: ComputeSquaredDistance,
36    {
37        if left.len() != right.len() {
38            return Err(());
39        }
40        left.iter()
41            .zip(right.iter())
42            .map(|(left, right)| left.compute_squared_distance(right))
43            .sum()
44    }
45}
46
47pub mod with_zero {
52    use crate::values::animated::ToAnimatedZero;
53    use crate::values::{
54        animated::{Animate, Procedure},
55        distance::{ComputeSquaredDistance, SquaredDistance},
56    };
57    use itertools::{EitherOrBoth, Itertools};
58    use std::iter::FromIterator;
59
60    #[allow(missing_docs)]
61    pub fn animate<T, C>(left: &[T], right: &[T], procedure: Procedure) -> Result<C, ()>
62    where
63        T: Animate + Clone + ToAnimatedZero,
64        C: FromIterator<T>,
65    {
66        if procedure == Procedure::Add {
67            return Ok(left.iter().chain(right.iter()).cloned().collect());
68        }
69        left.iter()
70            .zip_longest(right.iter())
71            .map(|it| match it {
72                EitherOrBoth::Both(left, right) => left.animate(right, procedure),
73                EitherOrBoth::Left(left) => left.animate(&left.to_animated_zero()?, procedure),
74                EitherOrBoth::Right(right) => right.to_animated_zero()?.animate(right, procedure),
75            })
76            .collect()
77    }
78
79    #[allow(missing_docs)]
80    pub fn squared_distance<T>(left: &[T], right: &[T]) -> Result<SquaredDistance, ()>
81    where
82        T: ToAnimatedZero + ComputeSquaredDistance,
83    {
84        left.iter()
85            .zip_longest(right.iter())
86            .map(|it| match it {
87                EitherOrBoth::Both(left, right) => left.compute_squared_distance(right),
88                EitherOrBoth::Left(item) | EitherOrBoth::Right(item) => {
89                    item.to_animated_zero()?.compute_squared_distance(item)
90                },
91            })
92            .sum()
93    }
94}
95
96pub mod repeatable_list {
98    use crate::values::{
99        animated::{Animate, Procedure},
100        distance::{ComputeSquaredDistance, SquaredDistance},
101    };
102    use std::iter::FromIterator;
103
104    #[allow(missing_docs)]
105    pub fn animate<T, C>(left: &[T], right: &[T], procedure: Procedure) -> Result<C, ()>
106    where
107        T: Animate,
108        C: FromIterator<T>,
109    {
110        use num_integer::lcm;
111        if left.is_empty() || right.is_empty() {
113            return Err(());
114        }
115        let len = lcm(left.len(), right.len());
116        left.iter()
117            .cycle()
118            .zip(right.iter().cycle())
119            .take(len)
120            .map(|(left, right)| left.animate(right, procedure))
121            .collect()
122    }
123
124    #[allow(missing_docs)]
125    pub fn squared_distance<T>(left: &[T], right: &[T]) -> Result<SquaredDistance, ()>
126    where
127        T: ComputeSquaredDistance,
128    {
129        use num_integer::lcm;
130        if left.is_empty() || right.is_empty() {
131            return Err(());
132        }
133        let len = lcm(left.len(), right.len());
134        left.iter()
135            .cycle()
136            .zip(right.iter().cycle())
137            .take(len)
138            .map(|(left, right)| left.compute_squared_distance(right))
139            .sum()
140    }
141}