mpdec 4.0.1

wrapper for libmpdec math library
Documentation
use crate::{Decimal, context::get_context, error::MPDecimalError};

use std::{ffi::CString, str::FromStr};

use mpdec_sys::mpd_qset_string;

macro_rules! gen_from_primitives_funcs {
    (
        $($func_name:ident($type:ty) => $mpd_qset_func:ident;)*
    ) => {
        $(
            pub fn $func_name(from: $type) -> Result<Decimal, MPDecimalError> {
                let result = Decimal::checked_new()?;

                let mut status: u32 = 0;

                unsafe {
                    mpdec_sys::$mpd_qset_func(
                        result.inner,
                        from,
                        &mut *get_context(),
                        &mut status,
                    );
                }

                MPDecimalError::from_status(status)?;

                Ok(result)
            }
        )*
    };
}

impl Decimal {
    gen_from_primitives_funcs!(
        from_u32(u32) => mpd_qset_u32;
        from_u64(u64) => mpd_qset_u64;
        from_i32(i32) => mpd_qset_i32;
        from_i64(i64) => mpd_qset_i64;
    );
    pub fn from_f32(value: f32) -> std::io::Result<Self> {
        Self::from_str(&value.to_string())
    }
    pub fn from_f64(value: f64) -> std::io::Result<Self> {
        Self::from_str(&value.to_string())
    }
}

impl FromStr for Decimal {
    type Err = std::io::Error;
    fn from_str(s: &str) -> Result<Self, Self::Err> {
        let cstr =
            CString::new(s).map_err(|_| std::io::Error::from(std::io::ErrorKind::InvalidData))?;
        let decimal = Self::checked_new()?;

        let mut status = 0_u32;

        unsafe {
            mpd_qset_string(
                decimal.inner,
                cstr.as_ptr(),
                &mut *get_context(),
                &mut status,
            )
        };

        MPDecimalError::from_status(status)?;
        Ok(decimal)
    }
}