1use indexmap::IndexMap;
2use std::hash::Hash;
3
4const FLOAT_EPSILON: f32 = 0.001;
5
6pub fn equals_float(a: f32, b: f32) -> bool {
7 (a - b).abs() < FLOAT_EPSILON
8}
9
10pub fn equals_float_quantized(a: f32, b: f32, precision: f32) -> bool {
11 (a / precision).round() as i64 == (b / precision).round() as i64
12}
13
14pub fn equals_optional<T, F>(a: &Option<T>, b: &Option<T>, mut equals: F) -> bool
15where
16 F: FnMut(&T, &T) -> bool,
17{
18 match (a, b) {
19 (None, None) => true,
20 (Some(av), Some(bv)) => equals(av, bv),
21 _ => false,
22 }
23}
24
25pub fn equals_array<T, F>(a: &[T], b: &[T], mut equals: F) -> bool
26where
27 F: FnMut(&T, &T) -> bool,
28{
29 a.len() == b.len() && a.iter().zip(b.iter()).all(|(x, y)| equals(x, y))
30}
31
32pub fn equals_record<K, V, F>(a: &IndexMap<K, V>, b: &IndexMap<K, V>, mut value_equals: F) -> bool
33where
34 K: Eq + Hash,
35 F: FnMut(&V, &V) -> bool,
36{
37 a.len() == b.len()
38 && a.iter()
39 .all(|(k, av)| b.get(k).is_some_and(|bv| value_equals(av, bv)))
40}