use crate::core::error::PlottingError;
use crate::data::traits::Data1D;
pub fn collect_finite_values<T, D>(data: &D) -> Result<Vec<f64>, PlottingError>
where
T: Into<f64> + Copy,
D: Data1D<T>,
{
if data.len() == 0 {
return Err(PlottingError::EmptyDataSet);
}
let values: Vec<f64> = (0..data.len())
.filter_map(|i| data.get(i))
.map(|v| (*v).into())
.filter(|v: &f64| v.is_finite())
.collect();
if values.is_empty() {
return Err(PlottingError::InvalidData {
message: "No finite values in data".to_string(),
position: None,
});
}
Ok(values)
}
pub fn collect_finite_values_sorted<T, D>(data: &D) -> Result<Vec<f64>, PlottingError>
where
T: Into<f64> + Copy,
D: Data1D<T>,
{
let mut values = collect_finite_values(data)?;
values.sort_by(|a, b| a.partial_cmp(b).unwrap_or(std::cmp::Ordering::Equal));
Ok(values)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_collect_finite_values_basic() {
let data = vec![1.0, 2.0, 3.0, 4.0, 5.0];
let result = collect_finite_values(&data).unwrap();
assert_eq!(result, vec![1.0, 2.0, 3.0, 4.0, 5.0]);
}
#[test]
fn test_collect_finite_values_filters_nan() {
let data = vec![1.0, f64::NAN, 3.0, f64::NAN, 5.0];
let result = collect_finite_values(&data).unwrap();
assert_eq!(result, vec![1.0, 3.0, 5.0]);
}
#[test]
fn test_collect_finite_values_filters_infinity() {
let data = vec![1.0, f64::INFINITY, 3.0, f64::NEG_INFINITY, 5.0];
let result = collect_finite_values(&data).unwrap();
assert_eq!(result, vec![1.0, 3.0, 5.0]);
}
#[test]
fn test_collect_finite_values_empty_data() {
let data: Vec<f64> = vec![];
let result = collect_finite_values(&data);
assert!(matches!(result, Err(PlottingError::EmptyDataSet)));
}
#[test]
fn test_collect_finite_values_all_nan() {
let data = vec![f64::NAN, f64::NAN, f64::NAN];
let result = collect_finite_values(&data);
assert!(matches!(result, Err(PlottingError::InvalidData { .. })));
}
#[test]
fn test_collect_finite_values_sorted() {
let data = vec![5.0, 2.0, 8.0, 1.0, 9.0];
let result = collect_finite_values_sorted(&data).unwrap();
assert_eq!(result, vec![1.0, 2.0, 5.0, 8.0, 9.0]);
}
#[test]
fn test_collect_finite_values_with_integers() {
let data: Vec<i32> = vec![1, 2, 3, 4, 5];
let result = collect_finite_values(&data).unwrap();
assert_eq!(result, vec![1.0, 2.0, 3.0, 4.0, 5.0]);
}
}