|
| 1 | +use super::error::AccumulatorError; |
1 | 2 | use crate::data_model::{ |
2 | 3 | AggregateCore, AggregationType, MergeableAccumulator, SerializableToSink, |
3 | 4 | SingleSubpopulationAggregate, SingleSubpopulationAggregateFactory, |
@@ -29,17 +30,17 @@ impl MinMaxAccumulator { |
29 | 30 | } |
30 | 31 | } |
31 | 32 |
|
32 | | - pub fn new(sub_type: String) -> Result<Self, String> { |
| 33 | + pub fn new(sub_type: String) -> Result<Self, AccumulatorError> { |
33 | 34 | match sub_type.as_str() { |
34 | 35 | "min" => Ok(Self::new_min()), |
35 | 36 | "max" => Ok(Self::new_max()), |
36 | | - _ => Err(format!("sub_type must be 'min' or 'max', got '{sub_type}'")), |
| 37 | + _ => Err(AccumulatorError::InvalidSubType(sub_type)), |
37 | 38 | } |
38 | 39 | } |
39 | 40 |
|
40 | | - pub fn with_value(value: f64, sub_type: String) -> Result<Self, String> { |
| 41 | + pub fn with_value(value: f64, sub_type: String) -> Result<Self, AccumulatorError> { |
41 | 42 | if sub_type != "min" && sub_type != "max" { |
42 | | - return Err(format!("sub_type must be 'min' or 'max', got '{sub_type}'")); |
| 43 | + return Err(AccumulatorError::InvalidSubType(sub_type)); |
43 | 44 | } |
44 | 45 | Ok(Self { value, sub_type }) |
45 | 46 | } |
@@ -120,15 +121,19 @@ impl MergeableAccumulator<MinMaxAccumulator> for MinMaxAccumulator { |
120 | 121 | accumulators: Vec<MinMaxAccumulator>, |
121 | 122 | ) -> Result<MinMaxAccumulator, Box<dyn std::error::Error + Send + Sync>> { |
122 | 123 | if accumulators.is_empty() { |
123 | | - return Err("No accumulators to merge".into()); |
| 124 | + return Err(AccumulatorError::EmptySlice.into()); |
124 | 125 | } |
125 | 126 |
|
126 | 127 | let sub_type = &accumulators[0].sub_type; |
127 | 128 |
|
128 | 129 | // Verify all accumulators have the same sub_type |
129 | 130 | for acc in &accumulators { |
130 | 131 | if acc.sub_type != *sub_type { |
131 | | - return Err("Cannot merge accumulators with different sub_types".into()); |
| 132 | + return Err(AccumulatorError::MergeTypeMismatch { |
| 133 | + expected: sub_type.clone(), |
| 134 | + got: acc.sub_type.clone(), |
| 135 | + } |
| 136 | + .into()); |
132 | 137 | } |
133 | 138 | } |
134 | 139 |
|
@@ -397,4 +402,16 @@ mod tests { |
397 | 402 | assert!(acc.query(Statistic::Min, None).is_err()); |
398 | 403 | assert_eq!(acc.type_name(), "MinMaxAccumulator"); |
399 | 404 | } |
| 405 | + |
| 406 | + #[test] |
| 407 | + fn test_new_invalid_sub_type() { |
| 408 | + let err = MinMaxAccumulator::new("mean".to_string()).unwrap_err(); |
| 409 | + assert!(matches!(err, AccumulatorError::InvalidSubType(s) if s == "mean")); |
| 410 | + } |
| 411 | + |
| 412 | + #[test] |
| 413 | + fn test_with_value_invalid_sub_type() { |
| 414 | + let err = MinMaxAccumulator::with_value(1.0, "sum".to_string()).unwrap_err(); |
| 415 | + assert!(matches!(err, AccumulatorError::InvalidSubType(s) if s == "sum")); |
| 416 | + } |
400 | 417 | } |
0 commit comments