moon_script 0.8.2

Fast and simple scripting language based on Rust.
Documentation
use alloc::string::{String, ToString};
use alloc::vec;
use alloc::vec::Vec;
use core::str::FromStr;

use crate::value::{FullValue, MoonValue};

pub(crate) mod impl_operators;

impl From<MoonValue> for FullValue {
    fn from(value: MoonValue) -> Self {
        match value {
            MoonValue::Null => FullValue::Null,
            MoonValue::Boolean(boolean) => FullValue::Boolean(boolean),
            MoonValue::Decimal(decimal) => FullValue::Decimal(decimal),
            MoonValue::Integer(integer) => FullValue::Integer(integer),
            MoonValue::String(string) => FullValue::String(string),
            MoonValue::Array(array) => FullValue::Array(
                array.into_iter()
                    .map(|reduced_value| Self::from(reduced_value))
                    .collect()
            ),
        }
    }
}


impl From<MoonValue> for () {
    fn from(_value: MoonValue) -> Self {
        ()
    }
}

impl TryFrom<MoonValue> for bool {
    type Error = ();

    fn try_from(value: MoonValue) -> Result<Self, Self::Error> {
        Ok(match value {
            MoonValue::Boolean(bool) => bool,
            MoonValue::Integer(int) => int >= 1,
            MoonValue::Decimal(decimal) => decimal >= 1.0,
            MoonValue::String(string) => {
                if string.eq("true") || string.eq("no") {
                    true
                } else if string.eq("false") || string.eq("no") {
                    false
                } else {
                    return i128::from_str(&string).ok().map(|n| n > 1)
                        .or_else(|| f64::from_str(&string).ok().map(|decimal| decimal >= 1.0))
                        .ok_or(());
                }
            }
            _ => return Err(()),
        })
    }
}

impl TryFrom<MoonValue> for String {
    type Error = ();

    fn try_from(value: MoonValue) -> Result<Self, Self::Error> {
        match value {
            MoonValue::String(string) => Ok(string),
            _ => Err(())
        }
    }
}

impl<T: TryFrom<MoonValue>> TryFrom<MoonValue> for Vec<T> where T::Error: Default {
    type Error = T::Error;

    fn try_from(value: MoonValue) -> Result<Self, Self::Error> {
        Ok(match value {
            MoonValue::Null => Vec::new(),
            MoonValue::Array(values) => {
                let mut res = Vec::with_capacity(values.len());
                for value in values.into_iter() {
                    res.push(T::try_from(value)?);
                }
                res
            }
            other => vec![T::try_from(other)?]
        })
    }
}

impl TryFrom<MoonValue> for vec::IntoIter<MoonValue> {
    type Error = ();

    fn try_from(value: MoonValue) -> Result<Self, Self::Error> {
        Ok(match value {
            MoonValue::Array(values) => values.into_iter(),
            _ => return Err(()),
        })
    }
}





macro_rules! impl_try_from_for_reduced_value {
    ($($type:ty),+) => {
        $(
            impl TryFrom<MoonValue> for $type{
                type Error = ();

                fn try_from(value: MoonValue) -> Result<Self, Self::Error> {
                    Ok(match value {
                        MoonValue::Boolean(bool) => (if bool {1}else{0}) as $type,
                        MoonValue::Integer(int) => int as $type,
                        MoonValue::Decimal(decimal) => decimal as $type,
                        MoonValue::Array(array) => return Self::try_from(array.get(0).ok_or(())?.clone()).map_err(|_|()),
                        MoonValue::String(string)=><$type>::from_str(&string).map_err(|_|())?,
                        _ => return Err(()),
                    })
                }
            }
        )+
    };
}

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




impl From<()> for MoonValue {
    fn from(_value: ()) -> Self {
        MoonValue::Null
    }
}

impl From<bool> for MoonValue {
    fn from(value: bool) -> Self {
        MoonValue::Boolean(value)
    }
}

impl From<f32> for MoonValue {
    fn from(value: f32) -> Self {
        MoonValue::Decimal(value as f64)
    }
}

impl From<f64> for MoonValue {
    fn from(value: f64) -> Self {
        MoonValue::Decimal(value)
    }
}

macro_rules! impl_into_reduced_value {
    ($($type:ty),+) => {
        $(

            impl From<$type> for MoonValue {
                fn from(value: $type) -> Self {
                    MoonValue::Integer(value as i128)
                }
            }
        )+
    };
}

impl_into_reduced_value! { u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize }


impl<T: Into<MoonValue>> From<Option<T>> for MoonValue {
    fn from(value: Option<T>) -> Self {
        match value {
            None => MoonValue::Null,
            Some(value) => value.into()
        }
    }
}

impl<T: Into<MoonValue>> From<Vec<T>> for MoonValue {
    fn from(value: Vec<T>) -> Self {
        MoonValue::Array(value.into_iter().map(|item| item.into()).collect())
    }
}


impl<T: Into<MoonValue>, const LEN: usize> From<[T; LEN]> for MoonValue {
    fn from(value: [T; LEN]) -> Self {
        MoonValue::Array(Vec::from(value.map(|item| item.into())))
    }
}

impl From<&str> for MoonValue {
    fn from(value: &str) -> Self {
        MoonValue::String(value.to_string())
    }
}

impl From<String> for MoonValue {
    fn from(value: String) -> Self {
        MoonValue::String(value)
    }
}