moon_script 0.8.2

Fast and simple scripting language based on Rust.
Documentation
use alloc::fmt::{Debug, Formatter};
use alloc::string::ToString;
use alloc::sync::Arc;

use paste::paste;

use crate::execution::RuntimeError;
use crate::value::MoonValue;

/// Allows to turn values to [crate::function::MoonFunction], but you shouldn't try to implement
/// this.
pub trait ToAbstractFunction<Params, Return, Function, Dummy> {

    /// Turns this object into a [crate::function::MoonFunction]
    fn abstract_function(self) -> MoonFunction;

    /// Placeholder
    fn dummy(_params: Params, _return_value: Return, _dummy: Dummy) {}
}

#[derive(Clone)]
pub struct MoonFunction {
    function: Arc<dyn Fn(&mut dyn Iterator<Item=Result<MoonValue, RuntimeError>>) -> Result<MoonValue, RuntimeError> + Send + Sync>,
    number_of_params: usize,
}

impl PartialEq for MoonFunction{
    fn eq(&self, other: &Self) -> bool {
        self.number_of_params == other.number_of_params
    }
}

impl Debug for MoonFunction {
    fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
        f.debug_struct("MoonFunction")
            .field("Function", &Arc::as_ptr(&self.function))
            .field("Number of params", &self.number_of_params)
            .finish()
    }
}

impl MoonFunction {
    #[inline]
    pub(crate) fn execute_iter<'values, ValuesIter>(&self, mut values: ValuesIter) -> Result<MoonValue, RuntimeError> where ValuesIter: Iterator<Item=Result<MoonValue, RuntimeError>> {
        (self.function)(&mut values)
    }

    #[inline]
    pub(crate) fn execute_into_iter<'values, ValuesIter>(&self, values: ValuesIter) -> Result<MoonValue, RuntimeError> where ValuesIter: IntoIterator<Item=Result<MoonValue, RuntimeError>> {
        (self.function)(&mut values.into_iter())
    }
}

macro_rules! impl_to_wrapped_function {
    (def { n: $params_len:literal names: $($param_names:ident)* }) => {
        paste!{
            impl<$($param_names, [<Error $param_names>], )* TReturn, TFunction, TError: ToString,>
                ToAbstractFunction<($($param_names,)*), TReturn, TFunction, u8> for TFunction
                where $($param_names: TryFrom<MoonValue, Error=[<Error $param_names>] > + 'static,)*
                      TReturn: Into<MoonValue> + 'static,
                      TFunction: Fn($($param_names),*) -> Result<TReturn,TError> + 'static + Send + Sync
            {
                #[allow(unused_mut)]
                #[allow(unused)]
                fn abstract_function(self) -> MoonFunction {
                    MoonFunction {
                        function: Arc::new(move |values| {
                            $(let paste::item!{[<$param_names:lower>]}  = <$param_names>::try_from(values.next()
                                .ok_or_else(|| RuntimeError::AnArgumentIsMissing{} )??)
                                .map_err(|_| RuntimeError::CannotParseArgument{} )?;)*

                            self($( paste::item!{[<$param_names:lower>]}  ),*)
                                .map(|return_value| return_value.into())
                                .map_err(|err| RuntimeError::FunctionError{ function_error_message:err.to_string() })
                        }),
                        number_of_params: $params_len,
                    }
                }
            }

            impl<$($param_names, [<Error $param_names>], )* TReturn, TFunction>
                ToAbstractFunction<($($param_names,)*), TReturn, TFunction, u16> for TFunction
                where $($param_names: TryFrom<MoonValue, Error=[<Error $param_names>]> + 'static,)*
                      TReturn: Into<MoonValue> + 'static,
                      TFunction: Fn($($param_names),*) -> TReturn + 'static + Send + Sync
            {
                #[allow(unused_mut)]
                #[allow(unused)]
                fn abstract_function(self) -> MoonFunction {
                    MoonFunction {
                        function: Arc::new(move |values| {
                            $(let paste::item!{[<$param_names:lower>]}  = <$param_names>::try_from(values.next()
                                .ok_or_else(|| RuntimeError::AnArgumentIsMissing{} )??)
                                .map_err(|_| RuntimeError::CannotParseArgument{} )?;)*

                            Ok(self($( paste::item!{[<$param_names:lower>]}  ),*)

                            .into())
                        }),
                        number_of_params: $params_len,
                    }
                }
            }
        }
    };

    ($(def { n: $params_len:literal names: $($param_names:ident)* })*) =>{
        $(impl_to_wrapped_function!{def { n: $params_len names: $($param_names)* }})*
    };
}


impl_to_wrapped_function! {
    def { n: 00 names: }
    def { n: 01 names: PA }
    def { n: 02 names: PA PB }
    def { n: 03 names: PA PB PC }
    def { n: 04 names: PA PB PC PD }
    def { n: 05 names: PA PB PC PD PE }
    def { n: 06 names: PA PB PC PD PE PF }
    def { n: 07 names: PA PB PC PD PE PF PG }
    def { n: 08 names: PA PB PC PD PE PF PG PH }
}

#[cfg(feature = "medium_functions")]
impl_to_wrapped_function! {
    def { n: 09 names: PA PB PC PD PE PF PG PH PI }
    def { n: 10 names: PA PB PC PD PE PF PG PH PI PJ }
    def { n: 11 names: PA PB PC PD PE PF PG PH PI PJ PK }
    def { n: 12 names: PA PB PC PD PE PF PG PH PI PJ PK PL }
    def { n: 13 names: PA PB PC PD PE PF PG PH PI PJ PK PL PM }
    def { n: 14 names: PA PB PC PD PE PF PG PH PI PJ PK PL PM PN }
    def { n: 15 names: PA PB PC PD PE PF PG PH PI PJ PK PL PM PN PO }
    def { n: 16 names: PA PB PC PD PE PF PG PH PI PJ PK PL PM PN PO PP }
}

#[cfg(feature = "big_functions")]
impl_to_wrapped_function! {
    def { n: 17 names: PA PB PC PD PE PF PG PH PI PJ PK PL PM PN PO PP PQ }
    def { n: 18 names: PA PB PC PD PE PF PG PH PI PJ PK PL PM PN PO PP PQ PR }
    def { n: 19 names: PA PB PC PD PE PF PG PH PI PJ PK PL PM PN PO PP PQ PR PS }
    def { n: 20 names: PA PB PC PD PE PF PG PH PI PJ PK PL PM PN PO PP PQ PR PS PU }
    def { n: 21 names: PA PB PC PD PE PF PG PH PI PJ PK PL PM PN PO PP PQ PR PS PU PV }
    def { n: 22 names: PA PB PC PD PE PF PG PH PI PJ PK PL PM PN PO PP PQ PR PS PU PV PT }
    def { n: 23 names: PA PB PC PD PE PF PG PH PI PJ PK PL PM PN PO PP PQ PR PS PU PV PT PW }
    def { n: 24 names: PA PB PC PD PE PF PG PH PI PJ PK PL PM PN PO PP PQ PR PS PU PV PT PW PX }
}

#[cfg(feature = "massive_functions")]
impl_to_wrapped_function! {
    def { n: 25 names: PA PB PC PD PE PF PG PH PI PJ PK PL PM PN PO PP PQ PR PS PU PV PT PW PX PZ }
    def { n: 26 names: PA PB PC PD PE PF PG PH PI PJ PK PL PM PN PO PP PQ PR PS PU PV PT PW PX PZ PY }
    def { n: 27 names: PA PB PC PD PE PF PG PH PI PJ PK PL PM PN PO PP PQ PR PS PU PV PT PW PX PZ PY PAA }
    def { n: 28 names: PA PB PC PD PE PF PG PH PI PJ PK PL PM PN PO PP PQ PR PS PU PV PT PW PX PZ PY PAA PAB }
    def { n: 29 names: PA PB PC PD PE PF PG PH PI PJ PK PL PM PN PO PP PQ PR PS PU PV PT PW PX PZ PY PAA PAB PAC }
    def { n: 30 names: PA PB PC PD PE PF PG PH PI PJ PK PL PM PN PO PP PQ PR PS PU PV PT PW PX PZ PY PAA PAB PAC PAD }
    def { n: 31 names: PA PB PC PD PE PF PG PH PI PJ PK PL PM PN PO PP PQ PR PS PU PV PT PW PX PZ PY PAA PAB PAC PAD PAE }
    def { n: 32 names: PA PB PC PD PE PF PG PH PI PJ PK PL PM PN PO PP PQ PR PS PU PV PT PW PX PZ PY PAA PAB PAC PAD PAE PAF }
    def { n: 33 names: PA PB PC PD PE PF PG PH PI PJ PK PL PM PN PO PP PQ PR PS PU PV PT PW PX PZ PY PAA PAB PAC PAD PAE PAF PAG }
    def { n: 34 names: PA PB PC PD PE PF PG PH PI PJ PK PL PM PN PO PP PQ PR PS PU PV PT PW PX PZ PY PAA PAB PAC PAD PAE PAF PAG PAH }
    def { n: 35 names: PA PB PC PD PE PF PG PH PI PJ PK PL PM PN PO PP PQ PR PS PU PV PT PW PX PZ PY PAA PAB PAC PAD PAE PAF PAG PAH PAI }
    def { n: 36 names: PA PB PC PD PE PF PG PH PI PJ PK PL PM PN PO PP PQ PR PS PU PV PT PW PX PZ PY PAA PAB PAC PAD PAE PAF PAG PAH PAI PAJ }
    def { n: 37 names: PA PB PC PD PE PF PG PH PI PJ PK PL PM PN PO PP PQ PR PS PU PV PT PW PX PZ PY PAA PAB PAC PAD PAE PAF PAG PAH PAI PAJ PAK }
    def { n: 38 names: PA PB PC PD PE PF PG PH PI PJ PK PL PM PN PO PP PQ PR PS PU PV PT PW PX PZ PY PAA PAB PAC PAD PAE PAF PAG PAH PAI PAJ PAK PAL }
    def { n: 39 names: PA PB PC PD PE PF PG PH PI PJ PK PL PM PN PO PP PQ PR PS PU PV PT PW PX PZ PY PAA PAB PAC PAD PAE PAF PAG PAH PAI PAJ PAK PAL PAM }
    def { n: 40 names: PA PB PC PD PE PF PG PH PI PJ PK PL PM PN PO PP PQ PR PS PU PV PT PW PX PZ PY PAA PAB PAC PAD PAE PAF PAG PAH PAI PAJ PAK PAL PAM PAN }
}