Skip to main content

graphrecords_query/capabilities/arithmetic/
divide.rs

1use crate::{
2    Failure, IndexValue, QueryResult, Scalar, ValueDomain, error::arithmetic::DivisionByZero,
3};
4use graphrecords_core::graphrecord::GraphRecordValue;
5
6pub trait ValueDivide: ValueDomain {
7    fn divide<'a>(
8        label: &'static str,
9        value: Self::Value<'a>,
10        argument: Self::Value<'a>,
11    ) -> QueryResult<Self::Value<'a>>;
12}
13
14fn is_division_by_zero(dividend: &GraphRecordValue, divisor: &GraphRecordValue) -> bool {
15    match (dividend, divisor) {
16        (
17            GraphRecordValue::Int(_) | GraphRecordValue::Float(_) | GraphRecordValue::Duration(_),
18            GraphRecordValue::Int(0),
19        ) => true,
20        (
21            GraphRecordValue::Int(_) | GraphRecordValue::Float(_),
22            GraphRecordValue::Float(divisor),
23        ) => *divisor == 0.0,
24        _ => false,
25    }
26}
27
28impl ValueDivide for Scalar {
29    fn divide<'a>(
30        label: &'static str,
31        value: Self::Value<'a>,
32        argument: Self::Value<'a>,
33    ) -> QueryResult<Self::Value<'a>> {
34        if is_division_by_zero(&value, &argument) {
35            return Err(Failure::new(label, DivisionByZero::new(value)));
36        }
37
38        (value / argument).map_err(|error| Failure::new(label, error))
39    }
40}
41
42impl ValueDivide for IndexValue<GraphRecordValue> {
43    fn divide<'a>(
44        label: &'static str,
45        value: Self::Value<'a>,
46        argument: Self::Value<'a>,
47    ) -> QueryResult<Self::Value<'a>> {
48        if is_division_by_zero(&value, &argument) {
49            return Err(Failure::new(label, DivisionByZero::new(value)));
50        }
51
52        (value / argument).map_err(|error| Failure::new(label, error))
53    }
54}