use crate::util::{
AggregateError, AggregateUtils, BigDecimalValue, NumberIterableValue, NumberValue,
};
#[derive(Clone, Copy, Debug, Default)]
pub struct Aggregates;
impl Aggregates {
#[must_use]
pub const fn new() -> Self {
Self
}
pub fn sum_iterable(
&self,
target: Option<&dyn NumberIterableValue>,
) -> Result<Option<BigDecimalValue>, AggregateError> {
AggregateUtils::sum_iterable(target)
}
pub fn sum_numbers(
&self,
target: Option<&[Option<NumberValue>]>,
) -> Result<Option<BigDecimalValue>, AggregateError> {
AggregateUtils::sum_numbers(target)
}
pub fn sum_bytes(
&self,
target: Option<&[i8]>,
) -> Result<Option<BigDecimalValue>, AggregateError> {
AggregateUtils::sum_bytes(target)
}
pub fn sum_shorts(
&self,
target: Option<&[i16]>,
) -> Result<Option<BigDecimalValue>, AggregateError> {
AggregateUtils::sum_shorts(target)
}
pub fn sum_ints(
&self,
target: Option<&[i32]>,
) -> Result<Option<BigDecimalValue>, AggregateError> {
AggregateUtils::sum_ints(target)
}
pub fn sum_longs(
&self,
target: Option<&[i64]>,
) -> Result<Option<BigDecimalValue>, AggregateError> {
AggregateUtils::sum_longs(target)
}
pub fn sum_floats(
&self,
target: Option<&[f32]>,
) -> Result<Option<BigDecimalValue>, AggregateError> {
AggregateUtils::sum_floats(target)
}
pub fn sum_doubles(
&self,
target: Option<&[f64]>,
) -> Result<Option<BigDecimalValue>, AggregateError> {
AggregateUtils::sum_doubles(target)
}
pub fn avg_iterable(
&self,
target: Option<&dyn NumberIterableValue>,
) -> Result<Option<BigDecimalValue>, AggregateError> {
AggregateUtils::avg_iterable(target)
}
pub fn avg_numbers(
&self,
target: Option<&[Option<NumberValue>]>,
) -> Result<Option<BigDecimalValue>, AggregateError> {
AggregateUtils::avg_numbers(target)
}
pub fn avg_bytes(
&self,
target: Option<&[i8]>,
) -> Result<Option<BigDecimalValue>, AggregateError> {
AggregateUtils::avg_bytes(target)
}
pub fn avg_shorts(
&self,
target: Option<&[i16]>,
) -> Result<Option<BigDecimalValue>, AggregateError> {
AggregateUtils::avg_shorts(target)
}
pub fn avg_ints(
&self,
target: Option<&[i32]>,
) -> Result<Option<BigDecimalValue>, AggregateError> {
AggregateUtils::avg_ints(target)
}
pub fn avg_longs(
&self,
target: Option<&[i64]>,
) -> Result<Option<BigDecimalValue>, AggregateError> {
AggregateUtils::avg_longs(target)
}
pub fn avg_floats(
&self,
target: Option<&[f32]>,
) -> Result<Option<BigDecimalValue>, AggregateError> {
AggregateUtils::avg_floats(target)
}
pub fn avg_doubles(
&self,
target: Option<&[f64]>,
) -> Result<Option<BigDecimalValue>, AggregateError> {
AggregateUtils::avg_doubles(target)
}
}
#[cfg(test)]
mod tests {
use crate::util::{AggregateError, BigDecimalValue, NumberListValue, NumberValue};
use super::Aggregates;
#[test]
fn constructs_and_delegates_every_java_overload() {
let aggregates = Aggregates::new();
let default = Aggregates;
assert_eq!(format!("{aggregates:?}"), format!("{default:?}"));
let numbers = [Some(NumberValue::Integer(1)), Some(NumberValue::Integer(2))];
let iterable_numbers = NumberListValue::new(numbers.to_vec());
assert_eq!(
aggregates
.sum_iterable(Some(&iterable_numbers))
.expect("sum")
.expect("value")
.to_string(),
"3"
);
assert_eq!(
aggregates
.sum_numbers(Some(&numbers))
.expect("sum")
.expect("value")
.to_string(),
"3"
);
assert_eq!(render(aggregates.sum_bytes(Some(&[1, 2]))), "3");
assert_eq!(render(aggregates.sum_shorts(Some(&[1, 2]))), "3");
assert_eq!(render(aggregates.sum_ints(Some(&[1, 2]))), "3");
assert_eq!(render(aggregates.sum_longs(Some(&[1, 2]))), "3");
assert_eq!(render(aggregates.sum_floats(Some(&[0.5, 0.25]))), "0.75");
assert_eq!(render(aggregates.sum_doubles(Some(&[0.5, 0.25]))), "0.75");
assert_eq!(
aggregates
.avg_iterable(Some(&iterable_numbers))
.expect("avg")
.expect("value")
.to_string(),
"1.5"
);
assert_eq!(
aggregates
.avg_numbers(Some(&numbers))
.expect("avg")
.expect("value")
.to_string(),
"1.5"
);
assert_eq!(render(aggregates.avg_bytes(Some(&[1, 2]))), "1.5");
assert_eq!(render(aggregates.avg_shorts(Some(&[1, 2]))), "1.5");
assert_eq!(render(aggregates.avg_ints(Some(&[1, 2]))), "1.5");
assert_eq!(render(aggregates.avg_longs(Some(&[1, 2]))), "1.5");
assert_eq!(render(aggregates.avg_floats(Some(&[0.5, 0.25]))), "0.375");
assert_eq!(render(aggregates.avg_doubles(Some(&[0.5, 0.25]))), "0.375");
}
#[test]
fn facade_preserves_errors_and_empty_null_result() {
let aggregates = Aggregates::new();
assert_eq!(
aggregates.sum_ints(None),
Err(AggregateError::IllegalArgument {
message: "Cannot aggregate on null"
})
);
assert_eq!(aggregates.avg_ints(Some(&[])).expect("empty"), None);
}
fn render(result: Result<Option<BigDecimalValue>, AggregateError>) -> String {
result.expect("aggregate").expect("value").to_string()
}
}