Framework for embedding localizations into Rust types
//! Implementations of `Localize` for all primitive number types
//! These just convert to a `Decimal` and then use its implementation

use crate::{Context, Localize};

use fixed_decimal::{Decimal, FloatPrecision};
use writeable::Writeable;

macro_rules! impl_integer {
    ($numeric_type:ty) => {
        impl Localize for $numeric_type {
            fn localize(&self, context: &Context, buffer: &mut String) {
                let fixed_decimal = Decimal::from(*self);
                fixed_decimal.localize(context, buffer);
            }
        }
    };
}

macro_rules! impl_float {
    ($numeric_type:ty) => {
        impl Localize for $numeric_type {
            fn localize(&self, context: &Context, buffer: &mut String) {
                let fixed_decimal =
                    Decimal::try_from_f64(f64::from(*self), FloatPrecision::RoundTrip).unwrap();
                fixed_decimal.localize(context, buffer);
            }
        }
    };
}

impl_integer!(u8);
impl_integer!(u16);
impl_integer!(u32);
impl_integer!(u64);
impl_integer!(u128);
impl_integer!(usize);
impl_integer!(i8);
impl_integer!(i16);
impl_integer!(i32);
impl_integer!(i64);
impl_integer!(i128);
impl_integer!(isize);

impl_float!(f32);
impl_float!(f64);

impl Localize for Decimal {
    fn localize(&self, context: &Context, buffer: &mut String) {
        let formatter = context.decimal_formatter();

        let formatted_decimal = formatter.format(self);
        formatted_decimal.write_to(buffer).unwrap();
    }
}