Skip to content

Commit 38108b6

Browse files
committed
return individual flags for the sequence in single_*_than_any
1 parent 8a3e4d1 commit 38108b6

5 files changed

+186
-172
lines changed

src/checks/consistency.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
mod greater_than;
22
pub use greater_than::greater_than;
33

4-
mod single_greater_than_min;
5-
pub use single_greater_than_min::single_greater_than_min;
4+
mod single_greater_than_any;
5+
pub use single_greater_than_any::single_greater_than_any;
66

7-
mod single_less_than_max;
8-
pub use single_less_than_max::single_less_than_max;
7+
mod single_less_than_any;
8+
pub use single_less_than_any::single_less_than_any;
99

1010
mod single_outside_sequence;
1111
pub use single_outside_sequence::single_outside_sequence;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
use crate::Flag;
2+
3+
/// Compares a single value to a higher resolution sequence, where the single value should never
4+
/// be greater than any value in the sequence (including an adjustment)
5+
///
6+
/// Returns:
7+
/// For the single value:
8+
/// - [`Flag::DataMissing`] if the single value is missing,
9+
/// - [`Flag::Fail`] if this invariant is broken (i.e the single value is greater than the any element
10+
/// of the sequence plus the adjustment),
11+
/// - [`Flag::DataMissing`] if any of the elements is missing, as we cannot be sure a missing data
12+
/// point did not violate the invariant.
13+
/// - [`Flag::Pass`] otherwise.
14+
///
15+
/// For each element in the sequence:
16+
/// - [`Flag::DataMissing`] if the single value or the element is missing,
17+
/// - [`Flag::Fail`] if this invariant is broken (i.e the single value is greater than the element
18+
/// plus the adjustment),
19+
/// - [`Flag::Pass`] otherwise.
20+
pub fn single_greater_than_any(
21+
single: Option<f32>,
22+
sequence: &[Option<f32>],
23+
adjustment: f32,
24+
) -> (Flag, Vec<Flag>) {
25+
let single = match single {
26+
Some(value) => value,
27+
None => {
28+
// If the single is missing, we can't do a check at all
29+
return (Flag::DataMissing, vec![Flag::DataMissing; sequence.len()]);
30+
}
31+
};
32+
33+
let sequence_flags: Vec<Flag> = sequence
34+
.iter()
35+
// for each element of the sequence
36+
.map(|elem| match elem {
37+
Some(value) => {
38+
if single > value + adjustment {
39+
// if the value violates the invariant, flag it as Fail
40+
Flag::Fail
41+
} else {
42+
Flag::Pass
43+
}
44+
}
45+
// if the value is missing, flag as DataMissing
46+
None => Flag::DataMissing,
47+
})
48+
.collect();
49+
50+
let single_flag = if sequence_flags.iter().any(|f| *f == Flag::Fail) {
51+
// if the invariant was violated for any element of the sequence, it was for the single
52+
// value too
53+
Flag::Fail
54+
} else if sequence_flags.iter().any(|f| *f == Flag::DataMissing) {
55+
// else if no violation was detected, but there was missing data in the sequence, we cannot
56+
// say for sure that the invariant wasn't invalidated
57+
Flag::DataMissing
58+
} else {
59+
Flag::Pass
60+
};
61+
62+
(single_flag, sequence_flags)
63+
}
64+
65+
#[cfg(test)]
66+
mod tests {
67+
use super::*;
68+
69+
#[test]
70+
fn test_single_less_than_max() {
71+
assert_eq!(
72+
single_greater_than_any(Some(1.), &[Some(1.), Some(2.), Some(2.)], 0.2),
73+
(Flag::Pass, vec![Flag::Pass, Flag::Pass, Flag::Pass])
74+
);
75+
assert_eq!(
76+
single_greater_than_any(Some(1.), &[Some(1.), Some(2.), Some(2.)], -0.2),
77+
(Flag::Fail, vec![Flag::Fail, Flag::Pass, Flag::Pass])
78+
);
79+
assert_eq!(
80+
single_greater_than_any(Some(1.), &[Some(1.), None, Some(2.)], -0.2),
81+
(Flag::Fail, vec![Flag::Fail, Flag::DataMissing, Flag::Pass])
82+
);
83+
assert_eq!(
84+
single_greater_than_any(Some(1.), &[Some(1.), None, Some(2.)], 0.2),
85+
(
86+
Flag::DataMissing,
87+
vec![Flag::Pass, Flag::DataMissing, Flag::Pass]
88+
)
89+
);
90+
}
91+
}

src/checks/consistency/single_greater_than_min.rs

-84
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
use crate::Flag;
2+
3+
/// Compares a single value to a higher resolution sequence, where the single value should never
4+
/// be less than any value in the sequence (including an adjustment)
5+
///
6+
/// Returns:
7+
/// For the single value:
8+
/// - [`Flag::DataMissing`] if the single value is missing,
9+
/// - [`Flag::Fail`] if this invariant is broken (i.e the single value is less than the any element
10+
/// of the sequence plus the adjustment),
11+
/// - [`Flag::DataMissing`] if any of the elements is missing, as we cannot be sure a missing data
12+
/// point did not violate the invariant.
13+
/// - [`Flag::Pass`] otherwise.
14+
///
15+
/// For each element in the sequence:
16+
/// - [`Flag::DataMissing`] if the single value or the element is missing,
17+
/// - [`Flag::Fail`] if this invariant is broken (i.e the single value is less than the element
18+
/// plus the adjustment),
19+
/// - [`Flag::Pass`] otherwise.
20+
pub fn single_less_than_any(
21+
single: Option<f32>,
22+
sequence: &[Option<f32>],
23+
adjustment: f32,
24+
) -> (Flag, Vec<Flag>) {
25+
let single = match single {
26+
Some(value) => value,
27+
None => {
28+
// If the single is missing, we can't do a check at all
29+
return (Flag::DataMissing, vec![Flag::DataMissing; sequence.len()]);
30+
}
31+
};
32+
33+
let sequence_flags: Vec<Flag> = sequence
34+
.iter()
35+
// for each element of the sequence
36+
.map(|elem| match elem {
37+
Some(value) => {
38+
if single < value + adjustment {
39+
// if the value violates the invariant, flag it as Fail
40+
Flag::Fail
41+
} else {
42+
Flag::Pass
43+
}
44+
}
45+
// if the value is missing, flag as DataMissing
46+
None => Flag::DataMissing,
47+
})
48+
.collect();
49+
50+
let single_flag = if sequence_flags.iter().any(|f| *f == Flag::Fail) {
51+
// if the invariant was violated for any element of the sequence, it was for the single
52+
// value too
53+
Flag::Fail
54+
} else if sequence_flags.iter().any(|f| *f == Flag::DataMissing) {
55+
// else if no violation was detected, but there was missing data in the sequence, we cannot
56+
// say for sure that the invariant wasn't invalidated
57+
Flag::DataMissing
58+
} else {
59+
Flag::Pass
60+
};
61+
62+
(single_flag, sequence_flags)
63+
}
64+
65+
#[cfg(test)]
66+
mod tests {
67+
use super::*;
68+
69+
#[test]
70+
fn test_single_less_than_max() {
71+
assert_eq!(
72+
single_less_than_any(Some(1.), &[Some(1.), Some(0.), Some(0.)], 0.2),
73+
(Flag::Fail, vec![Flag::Fail, Flag::Pass, Flag::Pass])
74+
);
75+
assert_eq!(
76+
single_less_than_any(Some(1.), &[Some(1.), Some(0.), Some(0.)], -0.2),
77+
(Flag::Pass, vec![Flag::Pass, Flag::Pass, Flag::Pass])
78+
);
79+
assert_eq!(
80+
single_less_than_any(Some(1.), &[Some(1.), None, Some(0.)], -0.2),
81+
(
82+
Flag::DataMissing,
83+
vec![Flag::Pass, Flag::DataMissing, Flag::Pass]
84+
)
85+
);
86+
assert_eq!(
87+
single_less_than_any(Some(1.), &[Some(1.), None, Some(0.)], 0.2),
88+
(Flag::Fail, vec![Flag::Fail, Flag::DataMissing, Flag::Pass])
89+
);
90+
}
91+
}

src/checks/consistency/single_less_than_max.rs

-84
This file was deleted.

0 commit comments

Comments
 (0)