matreex 0.44.2

A simple matrix implementation.
Documentation
use super::super::Matrix;
use super::super::order::Order;
use core::ops::{Rem, RemAssign};

macro_rules! impl_helper {
    ($(($t:ty, $s:ty, $u:ty))*) => {
        $(
            impl<O> Rem<$s> for Matrix<$t, O>
            where
                O: Order
            {
                type Output = Matrix<$u, O>;

                fn rem(self, rhs: $s) -> Self::Output {
                    match self.scalar_operation_consume_self(&rhs, |element, scalar| element % *scalar) {
                        Err(error) => panic!("{error}"),
                        Ok(output) => output,
                    }
                }
            }

            impl<O> Rem<$s> for &Matrix<$t, O>
            where
                O: Order
            {
                type Output = Matrix<$u, O>;

                fn rem(self, rhs: $s) -> Self::Output {
                    match self.scalar_operation(&rhs, |element, scalar| *element % *scalar) {
                        Err(error) => panic!("{error}"),
                        Ok(output) => output,
                    }
                }
            }

            impl<O> Rem<Matrix<$t, O>> for $s
            where
                O: Order
            {
                type Output = Matrix<$u, O>;

                fn rem(self, rhs: Matrix<$t, O>) -> Self::Output {
                    match rhs.scalar_operation_consume_self(&self, |element, scalar| *scalar % element) {
                        Err(error) => panic!("{error}"),
                        Ok(output) => output,
                    }
                }
            }

            impl<O> Rem<&Matrix<$t, O>> for $s
            where
                O: Order
            {
                type Output = Matrix<$u, O>;

                fn rem(self, rhs: &Matrix<$t, O>) -> Self::Output {
                    match rhs.scalar_operation(&self, |element, scalar| *scalar % *element) {
                        Err(error) => panic!("{error}"),
                        Ok(output) => output,
                    }
                }
            }
        )*
    }
}

macro_rules! impl_primitive_scalar_rem {
    ($($t:ty)*) => {
        $(
            impl_helper! {
                ($t, $t, $t)
                ($t, &$t, $t)
                (&$t, $t, $t)
                (&$t, &$t, $t)
            }

            impl<O> RemAssign<$t> for Matrix<$t, O>
            where
                O: Order
            {
                fn rem_assign(&mut self, rhs: $t) {
                    self.scalar_operation_assign(&rhs, |element, scalar| *element %= *scalar);
                }
            }

            impl<O> RemAssign<&$t> for Matrix<$t, O>
            where
                O: Order
            {
                fn rem_assign(&mut self, rhs: &$t) {
                    self.scalar_operation_assign(&rhs, |element, scalar| *element %= *scalar);
                }
            }
        )*
    }
}

impl_primitive_scalar_rem! {u8 u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize f32 f64}

#[cfg(test)]
mod tests {
    use crate::error::Result;
    use crate::{dispatch_unary, matrix};

    #[test]
    #[allow(clippy::op_ref)]
    fn test_primitive_scalar_rem() -> Result<()> {
        dispatch_unary! {{
            let matrix = matrix![[1, 2, 3], [4, 5, 6]].with_order::<O>();
            let scalar = 2;
            let expected = matrix![[1, 0, 1], [0, 1, 0]];

            {
                let matrix = matrix.clone();
                let output = matrix % scalar;
                assert_eq!(output, expected);
            }

            {
                let matrix = matrix.clone();
                let output = matrix % &scalar;
                assert_eq!(output, expected);
            }

            {
                let output = &matrix % scalar;
                assert_eq!(output, expected);
            }

            {
                let output = &matrix % &scalar;
                assert_eq!(output, expected);
            }

            {
                let matrix = matrix.map_ref(|x| x)?;
                let output = matrix % scalar;
                assert_eq!(output, expected);
            }

            {
                let matrix = matrix.map_ref(|x| x)?;
                let output = matrix % &scalar;
                assert_eq!(output, expected);
            }

            {
                let matrix = matrix.map_ref(|x| x)?;
                let output = &matrix % scalar;
                assert_eq!(output, expected);
            }

            {
                let matrix = matrix.map_ref(|x| x)?;
                let output = &matrix % &scalar;
                assert_eq!(output, expected);
            }
        }}

        Ok(())
    }

    #[test]
    #[allow(clippy::op_ref)]
    fn test_primitive_scalar_rem_rev() -> Result<()> {
        dispatch_unary! {{
            let matrix = matrix![[1, 2, 3], [4, 5, 6]].with_order::<O>();
            let scalar = 2;
            let expected = matrix![[0, 0, 2], [2, 2, 2]];

            {
                let matrix = matrix.clone();
                let output = scalar % matrix;
                assert_eq!(output, expected);
            }

            {
                let matrix = matrix.clone();
                let output = &scalar % matrix;
                assert_eq!(output, expected);
            }

            {
                let output = scalar % &matrix;
                assert_eq!(output, expected);
            }

            {
                let output = &scalar % &matrix;
                assert_eq!(output, expected);
            }

            {
                let matrix = matrix.map_ref(|x| x)?;
                let output = scalar % matrix;
                assert_eq!(output, expected);
            }

            {
                let matrix = matrix.map_ref(|x| x)?;
                let output = &scalar % matrix;
                assert_eq!(output, expected);
            }

            {
                let matrix = matrix.map_ref(|x| x)?;
                let output = scalar % &matrix;
                assert_eq!(output, expected);
            }

            {
                let matrix = matrix.map_ref(|x| x)?;
                let output = &scalar % &matrix;
                assert_eq!(output, expected);
            }
        }}

        Ok(())
    }

    #[test]
    fn test_primitive_scalar_rem_assign() {
        dispatch_unary! {{
            let matrix = matrix![[1, 2, 3], [4, 5, 6]].with_order::<O>();
            let scalar = 2;
            let expected = matrix![[1, 0, 1], [0, 1, 0]];

            {
                let mut matrix = matrix.clone();
                matrix %= scalar;
                assert_eq!(matrix, expected);
            }

            {
                let mut matrix = matrix.clone();
                matrix %= &scalar;
                assert_eq!(matrix, expected);
            }
        }}
    }
}