graphrecords_query/capabilities/arithmetic/
divide.rs1use 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}