graphblas_sparse_linear_algebra 0.62.0

Wrapper for SuiteSparse:GraphBLAS
Documentation
use std::mem::MaybeUninit;

use crate::collections::sparse_scalar::GetGraphblasSparseScalar;
use crate::collections::sparse_scalar::SparseScalar;
use crate::context::{CallGraphBlasContext, GetContext};
use crate::error::GraphblasErrorType;
use crate::error::LogicErrorType;
use crate::error::SparseLinearAlgebraError;
use crate::error::SparseLinearAlgebraErrorType;
use crate::graphblas_bindings::{
    GrB_Scalar_extractElement_BOOL, GrB_Scalar_extractElement_FP32, GrB_Scalar_extractElement_FP64,
    GrB_Scalar_extractElement_INT16, GrB_Scalar_extractElement_INT32,
    GrB_Scalar_extractElement_INT64, GrB_Scalar_extractElement_INT8,
    GrB_Scalar_extractElement_UINT16, GrB_Scalar_extractElement_UINT32,
    GrB_Scalar_extractElement_UINT64, GrB_Scalar_extractElement_UINT8,
};
use crate::value_type::utilities_to_implement_traits_for_all_value_types::implement_1_type_macro_for_all_value_types_and_typed_graphblas_function_with_implementation_type;
use crate::value_type::ConvertScalar;
use crate::value_type::ValueType;

pub trait GetScalarValue<T: ValueType + Default> {
    fn value(&self) -> Result<Option<T>, SparseLinearAlgebraError>;
    fn value_or_default(&self) -> Result<T, SparseLinearAlgebraError>;
}

impl<T: ValueType + Default + GetScalarValueTyped<T>> GetScalarValue<T> for SparseScalar<T> {
    fn value(&self) -> Result<Option<T>, SparseLinearAlgebraError> {
        T::value(self)
    }

    fn value_or_default(&self) -> Result<T, SparseLinearAlgebraError> {
        T::value_or_default(self)
    }
}

pub trait GetScalarValueTyped<T: ValueType + Default> {
    fn value(scalar: &SparseScalar<T>) -> Result<Option<T>, SparseLinearAlgebraError>;
    fn value_or_default(scalar: &SparseScalar<T>) -> Result<T, SparseLinearAlgebraError>;
}

macro_rules! implement_get_scalar_value_for_built_in_type {
    ($value_type:ty, $graphblas_implementation_type:ty, $get_element_function:ident) => {
        impl GetScalarValueTyped<$value_type> for $value_type {
            fn value(
                scalar: &SparseScalar<$value_type>,
            ) -> Result<Option<$value_type>, SparseLinearAlgebraError> {
                let mut value: MaybeUninit<$graphblas_implementation_type> = MaybeUninit::uninit();

                let result = scalar.context_ref().call(
                    || unsafe {
                        $get_element_function(value.as_mut_ptr(), scalar.graphblas_scalar())
                    },
                    unsafe { &scalar.graphblas_scalar() },
                );

                match result {
                    Ok(_) => {
                        let value = unsafe { value.assume_init() };
                        Ok(Some(value.to_type()?))
                    }
                    Err(error) => match error.error_type() {
                        SparseLinearAlgebraErrorType::LogicErrorType(
                            LogicErrorType::GraphBlas(GraphblasErrorType::NoValue),
                        ) => Ok(None),
                        _ => Err(error),
                    },
                }
            }

            fn value_or_default(
                scalar: &SparseScalar<$value_type>,
            ) -> Result<$value_type, SparseLinearAlgebraError> {
                Ok(<$value_type>::value(scalar)?.unwrap_or_default())
            }
        }
    };
}

implement_1_type_macro_for_all_value_types_and_typed_graphblas_function_with_implementation_type!(
    implement_get_scalar_value_for_built_in_type,
    GrB_Scalar_extractElement
);