graphrecords-query 0.5.0

High-performance graph-based data records
Documentation
use crate::{
    Failure, IndexValue, QueryResult, Scalar, ValueDomain, error::arithmetic::DivisionByZero,
};
use graphrecords_core::graphrecord::GraphRecordValue;

pub trait ValueDivide: ValueDomain {
    fn divide<'a>(
        label: &'static str,
        value: Self::Value<'a>,
        argument: Self::Value<'a>,
    ) -> QueryResult<Self::Value<'a>>;
}

fn is_division_by_zero(dividend: &GraphRecordValue, divisor: &GraphRecordValue) -> bool {
    match (dividend, divisor) {
        (
            GraphRecordValue::Int(_) | GraphRecordValue::Float(_) | GraphRecordValue::Duration(_),
            GraphRecordValue::Int(0),
        ) => true,
        (
            GraphRecordValue::Int(_) | GraphRecordValue::Float(_),
            GraphRecordValue::Float(divisor),
        ) => *divisor == 0.0,
        _ => false,
    }
}

impl ValueDivide for Scalar {
    fn divide<'a>(
        label: &'static str,
        value: Self::Value<'a>,
        argument: Self::Value<'a>,
    ) -> QueryResult<Self::Value<'a>> {
        if is_division_by_zero(&value, &argument) {
            return Err(Failure::new(label, DivisionByZero::new(value)));
        }

        (value / argument).map_err(|error| Failure::new(label, error))
    }
}

impl ValueDivide for IndexValue<GraphRecordValue> {
    fn divide<'a>(
        label: &'static str,
        value: Self::Value<'a>,
        argument: Self::Value<'a>,
    ) -> QueryResult<Self::Value<'a>> {
        if is_division_by_zero(&value, &argument) {
            return Err(Failure::new(label, DivisionByZero::new(value)));
        }

        (value / argument).map_err(|error| Failure::new(label, error))
    }
}