Convert some packages into plugins.
This commit is contained in:
parent
2495b367e5
commit
c0dc47c9db
93
src/any.rs
93
src/any.rs
@ -535,45 +535,47 @@ impl Dynamic {
|
|||||||
/// ```
|
/// ```
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn from<T: Variant + Clone>(value: T) -> Self {
|
pub fn from<T: Variant + Clone>(value: T) -> Self {
|
||||||
let type_id = TypeId::of::<T>();
|
if TypeId::of::<T>() == TypeId::of::<INT>() {
|
||||||
|
|
||||||
if type_id == TypeId::of::<INT>() {
|
|
||||||
return <dyn Any>::downcast_ref::<INT>(&value)
|
return <dyn Any>::downcast_ref::<INT>(&value)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.clone()
|
.clone()
|
||||||
.into();
|
.into();
|
||||||
}
|
}
|
||||||
#[cfg(not(feature = "no_float"))]
|
#[cfg(not(feature = "no_float"))]
|
||||||
if type_id == TypeId::of::<FLOAT>() {
|
if TypeId::of::<T>() == TypeId::of::<FLOAT>() {
|
||||||
return <dyn Any>::downcast_ref::<FLOAT>(&value)
|
return <dyn Any>::downcast_ref::<FLOAT>(&value)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.clone()
|
.clone()
|
||||||
.into();
|
.into();
|
||||||
}
|
}
|
||||||
if type_id == TypeId::of::<bool>() {
|
if TypeId::of::<T>() == TypeId::of::<bool>() {
|
||||||
return <dyn Any>::downcast_ref::<bool>(&value)
|
return <dyn Any>::downcast_ref::<bool>(&value)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.clone()
|
.clone()
|
||||||
.into();
|
.into();
|
||||||
}
|
}
|
||||||
if type_id == TypeId::of::<char>() {
|
if TypeId::of::<T>() == TypeId::of::<char>() {
|
||||||
return <dyn Any>::downcast_ref::<char>(&value)
|
return <dyn Any>::downcast_ref::<char>(&value)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.clone()
|
.clone()
|
||||||
.into();
|
.into();
|
||||||
}
|
}
|
||||||
if type_id == TypeId::of::<ImmutableString>() {
|
if TypeId::of::<T>() == TypeId::of::<ImmutableString>() {
|
||||||
return <dyn Any>::downcast_ref::<ImmutableString>(&value)
|
return <dyn Any>::downcast_ref::<ImmutableString>(&value)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.clone()
|
.clone()
|
||||||
.into();
|
.into();
|
||||||
}
|
}
|
||||||
if type_id == TypeId::of::<()>() {
|
if TypeId::of::<T>() == TypeId::of::<()>() {
|
||||||
return ().into();
|
return ().into();
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut boxed = Box::new(value);
|
let mut boxed = Box::new(value);
|
||||||
|
|
||||||
|
boxed = match unsafe_cast_box::<_, Dynamic>(boxed) {
|
||||||
|
Ok(d) => return *d,
|
||||||
|
Err(val) => val,
|
||||||
|
};
|
||||||
boxed = match unsafe_cast_box::<_, String>(boxed) {
|
boxed = match unsafe_cast_box::<_, String>(boxed) {
|
||||||
Ok(s) => return (*s).into(),
|
Ok(s) => return (*s).into(),
|
||||||
Err(val) => val,
|
Err(val) => val,
|
||||||
@ -599,11 +601,6 @@ impl Dynamic {
|
|||||||
Err(val) => val,
|
Err(val) => val,
|
||||||
};
|
};
|
||||||
|
|
||||||
boxed = match unsafe_cast_box::<_, Dynamic>(boxed) {
|
|
||||||
Ok(d) => return *d,
|
|
||||||
Err(val) => val,
|
|
||||||
};
|
|
||||||
|
|
||||||
Self(Union::Variant(Box::new(boxed)))
|
Self(Union::Variant(Box::new(boxed)))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -660,8 +657,6 @@ impl Dynamic {
|
|||||||
/// ```
|
/// ```
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn try_cast<T: Variant>(self) -> Option<T> {
|
pub fn try_cast<T: Variant>(self) -> Option<T> {
|
||||||
let type_id = TypeId::of::<T>();
|
|
||||||
|
|
||||||
match self.0 {
|
match self.0 {
|
||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
#[cfg(not(feature = "sync"))]
|
#[cfg(not(feature = "sync"))]
|
||||||
@ -673,11 +668,11 @@ impl Dynamic {
|
|||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
|
|
||||||
if type_id == TypeId::of::<Dynamic>() {
|
if TypeId::of::<T>() == TypeId::of::<Dynamic>() {
|
||||||
return unsafe_cast_box::<_, T>(Box::new(self)).ok().map(|v| *v);
|
return unsafe_cast_box::<_, T>(Box::new(self)).ok().map(|v| *v);
|
||||||
}
|
}
|
||||||
|
|
||||||
if type_id == TypeId::of::<INT>() {
|
if TypeId::of::<T>() == TypeId::of::<INT>() {
|
||||||
return match self.0 {
|
return match self.0 {
|
||||||
Union::Int(value) => unsafe_try_cast(value),
|
Union::Int(value) => unsafe_try_cast(value),
|
||||||
_ => None,
|
_ => None,
|
||||||
@ -685,35 +680,35 @@ impl Dynamic {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "no_float"))]
|
#[cfg(not(feature = "no_float"))]
|
||||||
if type_id == TypeId::of::<FLOAT>() {
|
if TypeId::of::<T>() == TypeId::of::<FLOAT>() {
|
||||||
return match self.0 {
|
return match self.0 {
|
||||||
Union::Float(value) => unsafe_try_cast(value),
|
Union::Float(value) => unsafe_try_cast(value),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if type_id == TypeId::of::<bool>() {
|
if TypeId::of::<T>() == TypeId::of::<bool>() {
|
||||||
return match self.0 {
|
return match self.0 {
|
||||||
Union::Bool(value) => unsafe_try_cast(value),
|
Union::Bool(value) => unsafe_try_cast(value),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if type_id == TypeId::of::<ImmutableString>() {
|
if TypeId::of::<T>() == TypeId::of::<ImmutableString>() {
|
||||||
return match self.0 {
|
return match self.0 {
|
||||||
Union::Str(value) => unsafe_try_cast(value),
|
Union::Str(value) => unsafe_try_cast(value),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if type_id == TypeId::of::<String>() {
|
if TypeId::of::<T>() == TypeId::of::<String>() {
|
||||||
return match self.0 {
|
return match self.0 {
|
||||||
Union::Str(value) => unsafe_try_cast(value.into_owned()),
|
Union::Str(value) => unsafe_try_cast(value.into_owned()),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if type_id == TypeId::of::<char>() {
|
if TypeId::of::<T>() == TypeId::of::<char>() {
|
||||||
return match self.0 {
|
return match self.0 {
|
||||||
Union::Char(value) => unsafe_try_cast(value),
|
Union::Char(value) => unsafe_try_cast(value),
|
||||||
_ => None,
|
_ => None,
|
||||||
@ -721,7 +716,7 @@ impl Dynamic {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
if type_id == TypeId::of::<Array>() {
|
if TypeId::of::<T>() == TypeId::of::<Array>() {
|
||||||
return match self.0 {
|
return match self.0 {
|
||||||
Union::Array(value) => unsafe_cast_box::<_, T>(value).ok().map(|v| *v),
|
Union::Array(value) => unsafe_cast_box::<_, T>(value).ok().map(|v| *v),
|
||||||
_ => None,
|
_ => None,
|
||||||
@ -729,21 +724,21 @@ impl Dynamic {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
if type_id == TypeId::of::<Map>() {
|
if TypeId::of::<T>() == TypeId::of::<Map>() {
|
||||||
return match self.0 {
|
return match self.0 {
|
||||||
Union::Map(value) => unsafe_cast_box::<_, T>(value).ok().map(|v| *v),
|
Union::Map(value) => unsafe_cast_box::<_, T>(value).ok().map(|v| *v),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if type_id == TypeId::of::<FnPtr>() {
|
if TypeId::of::<T>() == TypeId::of::<FnPtr>() {
|
||||||
return match self.0 {
|
return match self.0 {
|
||||||
Union::FnPtr(value) => unsafe_cast_box::<_, T>(value).ok().map(|v| *v),
|
Union::FnPtr(value) => unsafe_cast_box::<_, T>(value).ok().map(|v| *v),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if type_id == TypeId::of::<()>() {
|
if TypeId::of::<T>() == TypeId::of::<()>() {
|
||||||
return match self.0 {
|
return match self.0 {
|
||||||
Union::Unit(value) => unsafe_try_cast(value),
|
Union::Unit(value) => unsafe_try_cast(value),
|
||||||
_ => None,
|
_ => None,
|
||||||
@ -928,72 +923,70 @@ impl Dynamic {
|
|||||||
/// Returns `None` if the cast fails, or if the value is shared.
|
/// Returns `None` if the cast fails, or if the value is shared.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub(crate) fn downcast_ref<T: Variant + Clone>(&self) -> Option<&T> {
|
pub(crate) fn downcast_ref<T: Variant + Clone>(&self) -> Option<&T> {
|
||||||
let type_id = TypeId::of::<T>();
|
if TypeId::of::<T>() == TypeId::of::<INT>() {
|
||||||
|
|
||||||
if type_id == TypeId::of::<INT>() {
|
|
||||||
return match &self.0 {
|
return match &self.0 {
|
||||||
Union::Int(value) => <dyn Any>::downcast_ref::<T>(value),
|
Union::Int(value) => <dyn Any>::downcast_ref::<T>(value),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
#[cfg(not(feature = "no_float"))]
|
#[cfg(not(feature = "no_float"))]
|
||||||
if type_id == TypeId::of::<FLOAT>() {
|
if TypeId::of::<T>() == TypeId::of::<FLOAT>() {
|
||||||
return match &self.0 {
|
return match &self.0 {
|
||||||
Union::Float(value) => <dyn Any>::downcast_ref::<T>(value),
|
Union::Float(value) => <dyn Any>::downcast_ref::<T>(value),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if type_id == TypeId::of::<bool>() {
|
if TypeId::of::<T>() == TypeId::of::<bool>() {
|
||||||
return match &self.0 {
|
return match &self.0 {
|
||||||
Union::Bool(value) => <dyn Any>::downcast_ref::<T>(value),
|
Union::Bool(value) => <dyn Any>::downcast_ref::<T>(value),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if type_id == TypeId::of::<ImmutableString>() {
|
if TypeId::of::<T>() == TypeId::of::<ImmutableString>() {
|
||||||
return match &self.0 {
|
return match &self.0 {
|
||||||
Union::Str(value) => <dyn Any>::downcast_ref::<T>(value),
|
Union::Str(value) => <dyn Any>::downcast_ref::<T>(value),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if type_id == TypeId::of::<String>() {
|
if TypeId::of::<T>() == TypeId::of::<String>() {
|
||||||
return match &self.0 {
|
return match &self.0 {
|
||||||
Union::Str(value) => <dyn Any>::downcast_ref::<T>(value.as_ref()),
|
Union::Str(value) => <dyn Any>::downcast_ref::<T>(value.as_ref()),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if type_id == TypeId::of::<char>() {
|
if TypeId::of::<T>() == TypeId::of::<char>() {
|
||||||
return match &self.0 {
|
return match &self.0 {
|
||||||
Union::Char(value) => <dyn Any>::downcast_ref::<T>(value),
|
Union::Char(value) => <dyn Any>::downcast_ref::<T>(value),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
if type_id == TypeId::of::<Array>() {
|
if TypeId::of::<T>() == TypeId::of::<Array>() {
|
||||||
return match &self.0 {
|
return match &self.0 {
|
||||||
Union::Array(value) => <dyn Any>::downcast_ref::<T>(value.as_ref()),
|
Union::Array(value) => <dyn Any>::downcast_ref::<T>(value.as_ref()),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
if type_id == TypeId::of::<Map>() {
|
if TypeId::of::<T>() == TypeId::of::<Map>() {
|
||||||
return match &self.0 {
|
return match &self.0 {
|
||||||
Union::Map(value) => <dyn Any>::downcast_ref::<T>(value.as_ref()),
|
Union::Map(value) => <dyn Any>::downcast_ref::<T>(value.as_ref()),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if type_id == TypeId::of::<FnPtr>() {
|
if TypeId::of::<T>() == TypeId::of::<FnPtr>() {
|
||||||
return match &self.0 {
|
return match &self.0 {
|
||||||
Union::FnPtr(value) => <dyn Any>::downcast_ref::<T>(value.as_ref()),
|
Union::FnPtr(value) => <dyn Any>::downcast_ref::<T>(value.as_ref()),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if type_id == TypeId::of::<()>() {
|
if TypeId::of::<T>() == TypeId::of::<()>() {
|
||||||
return match &self.0 {
|
return match &self.0 {
|
||||||
Union::Unit(value) => <dyn Any>::downcast_ref::<T>(value),
|
Union::Unit(value) => <dyn Any>::downcast_ref::<T>(value),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if type_id == TypeId::of::<Dynamic>() {
|
if TypeId::of::<T>() == TypeId::of::<Dynamic>() {
|
||||||
return <dyn Any>::downcast_ref::<T>(self);
|
return <dyn Any>::downcast_ref::<T>(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1011,66 +1004,64 @@ impl Dynamic {
|
|||||||
/// Returns `None` if the cast fails, or if the value is shared.
|
/// Returns `None` if the cast fails, or if the value is shared.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub(crate) fn downcast_mut<T: Variant + Clone>(&mut self) -> Option<&mut T> {
|
pub(crate) fn downcast_mut<T: Variant + Clone>(&mut self) -> Option<&mut T> {
|
||||||
let type_id = TypeId::of::<T>();
|
if TypeId::of::<T>() == TypeId::of::<INT>() {
|
||||||
|
|
||||||
if type_id == TypeId::of::<INT>() {
|
|
||||||
return match &mut self.0 {
|
return match &mut self.0 {
|
||||||
Union::Int(value) => <dyn Any>::downcast_mut::<T>(value),
|
Union::Int(value) => <dyn Any>::downcast_mut::<T>(value),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
#[cfg(not(feature = "no_float"))]
|
#[cfg(not(feature = "no_float"))]
|
||||||
if type_id == TypeId::of::<FLOAT>() {
|
if TypeId::of::<T>() == TypeId::of::<FLOAT>() {
|
||||||
return match &mut self.0 {
|
return match &mut self.0 {
|
||||||
Union::Float(value) => <dyn Any>::downcast_mut::<T>(value),
|
Union::Float(value) => <dyn Any>::downcast_mut::<T>(value),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if type_id == TypeId::of::<bool>() {
|
if TypeId::of::<T>() == TypeId::of::<bool>() {
|
||||||
return match &mut self.0 {
|
return match &mut self.0 {
|
||||||
Union::Bool(value) => <dyn Any>::downcast_mut::<T>(value),
|
Union::Bool(value) => <dyn Any>::downcast_mut::<T>(value),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if type_id == TypeId::of::<ImmutableString>() {
|
if TypeId::of::<T>() == TypeId::of::<ImmutableString>() {
|
||||||
return match &mut self.0 {
|
return match &mut self.0 {
|
||||||
Union::Str(value) => <dyn Any>::downcast_mut::<T>(value),
|
Union::Str(value) => <dyn Any>::downcast_mut::<T>(value),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if type_id == TypeId::of::<char>() {
|
if TypeId::of::<T>() == TypeId::of::<char>() {
|
||||||
return match &mut self.0 {
|
return match &mut self.0 {
|
||||||
Union::Char(value) => <dyn Any>::downcast_mut::<T>(value),
|
Union::Char(value) => <dyn Any>::downcast_mut::<T>(value),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
if type_id == TypeId::of::<Array>() {
|
if TypeId::of::<T>() == TypeId::of::<Array>() {
|
||||||
return match &mut self.0 {
|
return match &mut self.0 {
|
||||||
Union::Array(value) => <dyn Any>::downcast_mut::<T>(value.as_mut()),
|
Union::Array(value) => <dyn Any>::downcast_mut::<T>(value.as_mut()),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
if type_id == TypeId::of::<Map>() {
|
if TypeId::of::<T>() == TypeId::of::<Map>() {
|
||||||
return match &mut self.0 {
|
return match &mut self.0 {
|
||||||
Union::Map(value) => <dyn Any>::downcast_mut::<T>(value.as_mut()),
|
Union::Map(value) => <dyn Any>::downcast_mut::<T>(value.as_mut()),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if type_id == TypeId::of::<FnPtr>() {
|
if TypeId::of::<T>() == TypeId::of::<FnPtr>() {
|
||||||
return match &mut self.0 {
|
return match &mut self.0 {
|
||||||
Union::FnPtr(value) => <dyn Any>::downcast_mut::<T>(value.as_mut()),
|
Union::FnPtr(value) => <dyn Any>::downcast_mut::<T>(value.as_mut()),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if type_id == TypeId::of::<()>() {
|
if TypeId::of::<T>() == TypeId::of::<()>() {
|
||||||
return match &mut self.0 {
|
return match &mut self.0 {
|
||||||
Union::Unit(value) => <dyn Any>::downcast_mut::<T>(value),
|
Union::Unit(value) => <dyn Any>::downcast_mut::<T>(value),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if type_id == TypeId::of::<Dynamic>() {
|
if TypeId::of::<T>() == TypeId::of::<Dynamic>() {
|
||||||
return <dyn Any>::downcast_mut::<T>(self);
|
return <dyn Any>::downcast_mut::<T>(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,65 +1,126 @@
|
|||||||
use crate::def_package;
|
use crate::def_package;
|
||||||
use crate::module::FuncReturn;
|
use crate::plugin::*;
|
||||||
|
|
||||||
// Comparison operators
|
macro_rules! gen_cmp_functions {
|
||||||
pub fn lt<T: PartialOrd>(x: T, y: T) -> FuncReturn<bool> {
|
($op_name:tt = $op_fn:ident ( $($arg_type:ident),+ ) -> $return_type:ident) => {
|
||||||
Ok(x < y)
|
pub mod $op_fn { $(
|
||||||
}
|
pub mod $arg_type {
|
||||||
pub fn lte<T: PartialOrd>(x: T, y: T) -> FuncReturn<bool> {
|
use crate::plugin::*;
|
||||||
Ok(x <= y)
|
|
||||||
}
|
pub const OP_NAME: &'static str = $op_name;
|
||||||
pub fn gt<T: PartialOrd>(x: T, y: T) -> FuncReturn<bool> {
|
|
||||||
Ok(x > y)
|
#[export_fn]
|
||||||
}
|
pub fn cmp_func(x: $arg_type, y: $arg_type) -> $return_type {
|
||||||
pub fn gte<T: PartialOrd>(x: T, y: T) -> FuncReturn<bool> {
|
super::super::super::$op_fn(x, y)
|
||||||
Ok(x >= y)
|
}
|
||||||
}
|
}
|
||||||
pub fn eq<T: PartialEq>(x: T, y: T) -> FuncReturn<bool> {
|
)* }
|
||||||
Ok(x == y)
|
}
|
||||||
}
|
|
||||||
pub fn ne<T: PartialEq>(x: T, y: T) -> FuncReturn<bool> {
|
|
||||||
Ok(x != y)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Logic operators
|
macro_rules! reg_functions {
|
||||||
fn not(x: bool) -> FuncReturn<bool> {
|
($mod_name:ident += $root:ident :: $op_name:ident ( $($arg_type:ident),+ )) => {
|
||||||
Ok(!x)
|
$(set_exported_fn!($mod_name, $root::$op_name::$arg_type::OP_NAME, $root::$op_name::$arg_type::cmp_func);)*
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! reg_op {
|
|
||||||
($lib:expr, $op:expr, $func:ident, $($par:ty),*) => {
|
|
||||||
$( $lib.set_fn_2($op, $func::<$par>); )*
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def_package!(crate:LogicPackage:"Logical operators.", lib, {
|
def_package!(crate:LogicPackage:"Logical operators.", lib, {
|
||||||
if cfg!(not(feature = "only_i32")) && cfg!(not(feature = "only_i64")) {
|
#[cfg(not(feature = "only_i32"))]
|
||||||
reg_op!(lib, "<", lt, i8, u8, i16, u16, i32, u32, u64);
|
#[cfg(not(feature = "only_i64"))]
|
||||||
reg_op!(lib, "<=", lte, i8, u8, i16, u16, i32, u32, u64);
|
{
|
||||||
reg_op!(lib, ">", gt, i8, u8, i16, u16, i32, u32, u64);
|
reg_functions!(lib += cmp::lt(i8, u8, i16, u16, i32, u32, u64));
|
||||||
reg_op!(lib, ">=", gte, i8, u8, i16, u16, i32, u32, u64);
|
reg_functions!(lib += cmp::lte(i8, u8, i16, u16, i32, u32, u64));
|
||||||
reg_op!(lib, "==", eq, i8, u8, i16, u16, i32, u32, u64);
|
reg_functions!(lib += cmp::gt(i8, u8, i16, u16, i32, u32, u64));
|
||||||
reg_op!(lib, "!=", ne, i8, u8, i16, u16, i32, u32, u64);
|
reg_functions!(lib += cmp::gte(i8, u8, i16, u16, i32, u32, u64));
|
||||||
|
reg_functions!(lib += cmp::eq(i8, u8, i16, u16, i32, u32, u64));
|
||||||
|
reg_functions!(lib += cmp::ne(i8, u8, i16, u16, i32, u32, u64));
|
||||||
|
|
||||||
if cfg!(not(target_arch = "wasm32")) {
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
reg_op!(lib, "<", lt, i128, u128);
|
{
|
||||||
reg_op!(lib, "<=", lte, i128, u128);
|
reg_functions!(lib += cmp_128::lt(i128, u128));
|
||||||
reg_op!(lib, ">", gt, i128, u128);
|
reg_functions!(lib += cmp_128::lte(i128, u128));
|
||||||
reg_op!(lib, ">=", gte, i128, u128);
|
reg_functions!(lib += cmp_128::gt(i128, u128));
|
||||||
reg_op!(lib, "==", eq, i128, u128);
|
reg_functions!(lib += cmp_128::gte(i128, u128));
|
||||||
reg_op!(lib, "!=", ne, i128, u128);
|
reg_functions!(lib += cmp_128::eq(i128, u128));
|
||||||
|
reg_functions!(lib += cmp_128::ne(i128, u128));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "no_float"))]
|
#[cfg(not(feature = "no_float"))]
|
||||||
{
|
{
|
||||||
reg_op!(lib, "<", lt, f32);
|
reg_functions!(lib += cmp_float::lt(f32));
|
||||||
reg_op!(lib, "<=", lte, f32);
|
reg_functions!(lib += cmp_float::lte(f32));
|
||||||
reg_op!(lib, ">", gt, f32);
|
reg_functions!(lib += cmp_float::gt(f32));
|
||||||
reg_op!(lib, ">=", gte, f32);
|
reg_functions!(lib += cmp_float::gte(f32));
|
||||||
reg_op!(lib, "==", eq, f32);
|
reg_functions!(lib += cmp_float::eq(f32));
|
||||||
reg_op!(lib, "!=", ne, f32);
|
reg_functions!(lib += cmp_float::ne(f32));
|
||||||
}
|
}
|
||||||
|
|
||||||
lib.set_fn_1("!", not);
|
set_exported_fn!(lib, "!", not);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Comparison operators
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn lt<T: PartialOrd>(x: T, y: T) -> bool {
|
||||||
|
x < y
|
||||||
|
}
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn lte<T: PartialOrd>(x: T, y: T) -> bool {
|
||||||
|
x <= y
|
||||||
|
}
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn gt<T: PartialOrd>(x: T, y: T) -> bool {
|
||||||
|
x > y
|
||||||
|
}
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn gte<T: PartialOrd>(x: T, y: T) -> bool {
|
||||||
|
x >= y
|
||||||
|
}
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn eq<T: PartialEq>(x: T, y: T) -> bool {
|
||||||
|
x == y
|
||||||
|
}
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn ne<T: PartialEq>(x: T, y: T) -> bool {
|
||||||
|
x != y
|
||||||
|
}
|
||||||
|
|
||||||
|
// Logic operators
|
||||||
|
#[export_fn]
|
||||||
|
#[inline(always)]
|
||||||
|
fn not(x: bool) -> bool {
|
||||||
|
!x
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "only_i32"))]
|
||||||
|
#[cfg(not(feature = "only_i64"))]
|
||||||
|
mod cmp {
|
||||||
|
gen_cmp_functions!("<" = lt(i8, u8, i16, u16, i32, u32, u64) -> bool);
|
||||||
|
gen_cmp_functions!("<=" = lte(i8, u8, i16, u16, i32, u32, u64) -> bool);
|
||||||
|
gen_cmp_functions!(">" = gt(i8, u8, i16, u16, i32, u32, u64) -> bool);
|
||||||
|
gen_cmp_functions!(">=" = gte(i8, u8, i16, u16, i32, u32, u64) -> bool);
|
||||||
|
gen_cmp_functions!("==" = eq(i8, u8, i16, u16, i32, u32, u64) -> bool);
|
||||||
|
gen_cmp_functions!("!=" = ne(i8, u8, i16, u16, i32, u32, u64) -> bool);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "only_i32"))]
|
||||||
|
#[cfg(not(feature = "only_i64"))]
|
||||||
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
|
mod cmp_128 {
|
||||||
|
gen_cmp_functions!("<" = lt(i128, u128) -> bool);
|
||||||
|
gen_cmp_functions!("<=" = lte(i128, u128) -> bool);
|
||||||
|
gen_cmp_functions!(">" = gt(i128, u128) -> bool);
|
||||||
|
gen_cmp_functions!(">=" = gte(i128, u128) -> bool);
|
||||||
|
gen_cmp_functions!("==" = eq(i128, u128) -> bool);
|
||||||
|
gen_cmp_functions!("!=" = ne(i128, u128) -> bool);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "no_float"))]
|
||||||
|
mod cmp_float {
|
||||||
|
gen_cmp_functions!("<" = lt(f32) -> bool);
|
||||||
|
gen_cmp_functions!("<=" = lte(f32) -> bool);
|
||||||
|
gen_cmp_functions!(">" = gt(f32) -> bool);
|
||||||
|
gen_cmp_functions!(">=" = gte(f32) -> bool);
|
||||||
|
gen_cmp_functions!("==" = eq(f32) -> bool);
|
||||||
|
gen_cmp_functions!("!=" = ne(f32) -> bool);
|
||||||
|
}
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
use crate::def_package;
|
use crate::def_package;
|
||||||
use crate::module::Module;
|
|
||||||
use crate::parser::INT;
|
use crate::parser::INT;
|
||||||
use crate::plugin::*;
|
use crate::plugin::*;
|
||||||
|
|
||||||
@ -24,99 +23,6 @@ pub const MAX_INT: INT = i32::MAX;
|
|||||||
pub const MAX_INT: INT = i64::MAX;
|
pub const MAX_INT: INT = i64::MAX;
|
||||||
|
|
||||||
def_package!(crate:BasicMathPackage:"Basic mathematic functions.", lib, {
|
def_package!(crate:BasicMathPackage:"Basic mathematic functions.", lib, {
|
||||||
init_module(lib);
|
|
||||||
});
|
|
||||||
|
|
||||||
#[cfg(not(feature = "no_float"))]
|
|
||||||
#[export_module]
|
|
||||||
mod trig {
|
|
||||||
use crate::parser::FLOAT;
|
|
||||||
|
|
||||||
pub fn sin(x: FLOAT) -> FLOAT {
|
|
||||||
x.to_radians().sin()
|
|
||||||
}
|
|
||||||
pub fn cos(x: FLOAT) -> FLOAT {
|
|
||||||
x.to_radians().cos()
|
|
||||||
}
|
|
||||||
pub fn tan(x: FLOAT) -> FLOAT {
|
|
||||||
x.to_radians().tan()
|
|
||||||
}
|
|
||||||
pub fn sinh(x: FLOAT) -> FLOAT {
|
|
||||||
x.to_radians().sinh()
|
|
||||||
}
|
|
||||||
pub fn cosh(x: FLOAT) -> FLOAT {
|
|
||||||
x.to_radians().cosh()
|
|
||||||
}
|
|
||||||
pub fn tanh(x: FLOAT) -> FLOAT {
|
|
||||||
x.to_radians().tanh()
|
|
||||||
}
|
|
||||||
pub fn asin(x: FLOAT) -> FLOAT {
|
|
||||||
x.asin().to_degrees()
|
|
||||||
}
|
|
||||||
pub fn acos(x: FLOAT) -> FLOAT {
|
|
||||||
x.acos().to_degrees()
|
|
||||||
}
|
|
||||||
pub fn atan(x: FLOAT) -> FLOAT {
|
|
||||||
x.atan().to_degrees()
|
|
||||||
}
|
|
||||||
pub fn asinh(x: FLOAT) -> FLOAT {
|
|
||||||
x.asinh().to_degrees()
|
|
||||||
}
|
|
||||||
pub fn acosh(x: FLOAT) -> FLOAT {
|
|
||||||
x.acosh().to_degrees()
|
|
||||||
}
|
|
||||||
pub fn atanh(x: FLOAT) -> FLOAT {
|
|
||||||
x.atanh().to_degrees()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(not(feature = "no_float"))]
|
|
||||||
#[export_module]
|
|
||||||
mod float {
|
|
||||||
use crate::parser::FLOAT;
|
|
||||||
|
|
||||||
pub fn sqrt(x: FLOAT) -> FLOAT {
|
|
||||||
x.sqrt()
|
|
||||||
}
|
|
||||||
pub fn exp(x: FLOAT) -> FLOAT {
|
|
||||||
x.exp()
|
|
||||||
}
|
|
||||||
pub fn ln(x: FLOAT) -> FLOAT {
|
|
||||||
x.ln()
|
|
||||||
}
|
|
||||||
pub fn log(x: FLOAT, base: FLOAT) -> FLOAT {
|
|
||||||
x.log(base)
|
|
||||||
}
|
|
||||||
pub fn log10(x: FLOAT) -> FLOAT {
|
|
||||||
x.log10()
|
|
||||||
}
|
|
||||||
pub fn floor(x: FLOAT) -> FLOAT {
|
|
||||||
x.floor()
|
|
||||||
}
|
|
||||||
pub fn ceiling(x: FLOAT) -> FLOAT {
|
|
||||||
x.ceil()
|
|
||||||
}
|
|
||||||
pub fn round(x: FLOAT) -> FLOAT {
|
|
||||||
x.ceil()
|
|
||||||
}
|
|
||||||
pub fn int(x: FLOAT) -> FLOAT {
|
|
||||||
x.trunc()
|
|
||||||
}
|
|
||||||
pub fn fraction(x: FLOAT) -> FLOAT {
|
|
||||||
x.fract()
|
|
||||||
}
|
|
||||||
pub fn is_nan(x: FLOAT) -> bool {
|
|
||||||
x.is_nan()
|
|
||||||
}
|
|
||||||
pub fn is_finite(x: FLOAT) -> bool {
|
|
||||||
x.is_finite()
|
|
||||||
}
|
|
||||||
pub fn is_infinite(x: FLOAT) -> bool {
|
|
||||||
x.is_infinite()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn init_module(lib: &mut Module) {
|
|
||||||
#[cfg(not(feature = "no_float"))]
|
#[cfg(not(feature = "no_float"))]
|
||||||
{
|
{
|
||||||
// Floating point functions
|
// Floating point functions
|
||||||
@ -209,4 +115,93 @@ fn init_module(lib: &mut Module) {
|
|||||||
lib.set_fn_1("to_int", |x: f64| Ok(x as INT));
|
lib.set_fn_1("to_int", |x: f64| Ok(x as INT));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
#[cfg(not(feature = "no_float"))]
|
||||||
|
#[export_module]
|
||||||
|
mod trig {
|
||||||
|
use crate::parser::FLOAT;
|
||||||
|
|
||||||
|
pub fn sin(x: FLOAT) -> FLOAT {
|
||||||
|
x.to_radians().sin()
|
||||||
|
}
|
||||||
|
pub fn cos(x: FLOAT) -> FLOAT {
|
||||||
|
x.to_radians().cos()
|
||||||
|
}
|
||||||
|
pub fn tan(x: FLOAT) -> FLOAT {
|
||||||
|
x.to_radians().tan()
|
||||||
|
}
|
||||||
|
pub fn sinh(x: FLOAT) -> FLOAT {
|
||||||
|
x.to_radians().sinh()
|
||||||
|
}
|
||||||
|
pub fn cosh(x: FLOAT) -> FLOAT {
|
||||||
|
x.to_radians().cosh()
|
||||||
|
}
|
||||||
|
pub fn tanh(x: FLOAT) -> FLOAT {
|
||||||
|
x.to_radians().tanh()
|
||||||
|
}
|
||||||
|
pub fn asin(x: FLOAT) -> FLOAT {
|
||||||
|
x.asin().to_degrees()
|
||||||
|
}
|
||||||
|
pub fn acos(x: FLOAT) -> FLOAT {
|
||||||
|
x.acos().to_degrees()
|
||||||
|
}
|
||||||
|
pub fn atan(x: FLOAT) -> FLOAT {
|
||||||
|
x.atan().to_degrees()
|
||||||
|
}
|
||||||
|
pub fn asinh(x: FLOAT) -> FLOAT {
|
||||||
|
x.asinh().to_degrees()
|
||||||
|
}
|
||||||
|
pub fn acosh(x: FLOAT) -> FLOAT {
|
||||||
|
x.acosh().to_degrees()
|
||||||
|
}
|
||||||
|
pub fn atanh(x: FLOAT) -> FLOAT {
|
||||||
|
x.atanh().to_degrees()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "no_float"))]
|
||||||
|
#[export_module]
|
||||||
|
mod float {
|
||||||
|
use crate::parser::FLOAT;
|
||||||
|
|
||||||
|
pub fn sqrt(x: FLOAT) -> FLOAT {
|
||||||
|
x.sqrt()
|
||||||
|
}
|
||||||
|
pub fn exp(x: FLOAT) -> FLOAT {
|
||||||
|
x.exp()
|
||||||
|
}
|
||||||
|
pub fn ln(x: FLOAT) -> FLOAT {
|
||||||
|
x.ln()
|
||||||
|
}
|
||||||
|
pub fn log(x: FLOAT, base: FLOAT) -> FLOAT {
|
||||||
|
x.log(base)
|
||||||
|
}
|
||||||
|
pub fn log10(x: FLOAT) -> FLOAT {
|
||||||
|
x.log10()
|
||||||
|
}
|
||||||
|
pub fn floor(x: FLOAT) -> FLOAT {
|
||||||
|
x.floor()
|
||||||
|
}
|
||||||
|
pub fn ceiling(x: FLOAT) -> FLOAT {
|
||||||
|
x.ceil()
|
||||||
|
}
|
||||||
|
pub fn round(x: FLOAT) -> FLOAT {
|
||||||
|
x.ceil()
|
||||||
|
}
|
||||||
|
pub fn int(x: FLOAT) -> FLOAT {
|
||||||
|
x.trunc()
|
||||||
|
}
|
||||||
|
pub fn fraction(x: FLOAT) -> FLOAT {
|
||||||
|
x.fract()
|
||||||
|
}
|
||||||
|
pub fn is_nan(x: FLOAT) -> bool {
|
||||||
|
x.is_nan()
|
||||||
|
}
|
||||||
|
pub fn is_finite(x: FLOAT) -> bool {
|
||||||
|
x.is_finite()
|
||||||
|
}
|
||||||
|
pub fn is_infinite(x: FLOAT) -> bool {
|
||||||
|
x.is_infinite()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,8 @@ use super::logic::{eq, gt, gte, lt, lte, ne};
|
|||||||
use super::math_basic::MAX_INT;
|
use super::math_basic::MAX_INT;
|
||||||
|
|
||||||
use crate::def_package;
|
use crate::def_package;
|
||||||
|
use crate::engine::make_getter;
|
||||||
|
use crate::plugin::*;
|
||||||
use crate::result::EvalAltResult;
|
use crate::result::EvalAltResult;
|
||||||
|
|
||||||
#[cfg(not(feature = "no_float"))]
|
#[cfg(not(feature = "no_float"))]
|
||||||
@ -26,68 +28,38 @@ use instant::Instant;
|
|||||||
|
|
||||||
def_package!(crate:BasicTimePackage:"Basic timing utilities.", lib, {
|
def_package!(crate:BasicTimePackage:"Basic timing utilities.", lib, {
|
||||||
// Register date/time functions
|
// Register date/time functions
|
||||||
lib.set_fn_0("timestamp", || Ok(Instant::now()));
|
set_exported_fn!(lib, "timestamp", create_timestamp);
|
||||||
|
set_exported_fn!(lib, "elapsed", elapsed);
|
||||||
|
|
||||||
lib.set_fn_2(
|
#[cfg(not(feature = "no_object"))]
|
||||||
"-",
|
set_exported_fn!(lib, make_getter("elapsed"), elapsed);
|
||||||
|ts1: Instant, ts2: Instant| {
|
|
||||||
if ts2 > ts1 {
|
|
||||||
#[cfg(not(feature = "no_float"))]
|
|
||||||
return Ok(-(ts2 - ts1).as_secs_f64());
|
|
||||||
|
|
||||||
#[cfg(feature = "no_float")]
|
set_exported_fn!(lib, "-", time_diff);
|
||||||
{
|
|
||||||
let seconds = (ts2 - ts1).as_secs();
|
|
||||||
|
|
||||||
#[cfg(not(feature = "unchecked"))]
|
//lib.merge(&exported_module!(time_compare));
|
||||||
if seconds > (MAX_INT as u64) {
|
|
||||||
return EvalAltResult::ErrorArithmetic(
|
|
||||||
format!(
|
|
||||||
"Integer overflow for timestamp duration: {}",
|
|
||||||
-(seconds as i64)
|
|
||||||
),
|
|
||||||
Position::none(),
|
|
||||||
).into();
|
|
||||||
}
|
|
||||||
|
|
||||||
return Ok(-(seconds as INT));
|
lib.set_fn_2("<", |x:Instant, y:Instant| Ok(lt(x, y)));
|
||||||
}
|
lib.set_fn_2("<=", |x:Instant, y:Instant| Ok(lte(x, y)));
|
||||||
} else {
|
lib.set_fn_2(">", |x:Instant, y:Instant| Ok(gt(x, y)));
|
||||||
#[cfg(not(feature = "no_float"))]
|
lib.set_fn_2(">=", |x:Instant, y:Instant| Ok(gte(x, y)));
|
||||||
return Ok((ts1 - ts2).as_secs_f64());
|
lib.set_fn_2("==", |x:Instant, y:Instant| Ok(eq(x, y)));
|
||||||
|
lib.set_fn_2("!=", |x:Instant, y:Instant| Ok(ne(x, y)));
|
||||||
|
});
|
||||||
|
|
||||||
#[cfg(feature = "no_float")]
|
#[export_fn]
|
||||||
{
|
fn create_timestamp() -> Instant {
|
||||||
let seconds = (ts1 - ts2).as_secs();
|
Instant::now()
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "unchecked"))]
|
#[cfg(not(feature = "no_float"))]
|
||||||
if seconds > (MAX_INT as u64) {
|
#[export_fn]
|
||||||
return EvalAltResult::ErrorArithmetic(
|
fn elapsed(timestamp: &mut Instant) -> FLOAT {
|
||||||
format!("Integer overflow for timestamp duration: {}", seconds),
|
timestamp.elapsed().as_secs_f64() as FLOAT
|
||||||
Position::none(),
|
}
|
||||||
).into();
|
|
||||||
}
|
|
||||||
|
|
||||||
return Ok(seconds as INT);
|
#[cfg(feature = "no_float")]
|
||||||
}
|
#[export_fn(return_raw)]
|
||||||
}
|
fn elapsed(timestamp: &mut Instant) -> Result<Dynamic, Box<EvalAltResult>> {
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
lib.set_fn_2("<", lt::<Instant>);
|
|
||||||
lib.set_fn_2("<=", lte::<Instant>);
|
|
||||||
lib.set_fn_2(">", gt::<Instant>);
|
|
||||||
lib.set_fn_2(">=", gte::<Instant>);
|
|
||||||
lib.set_fn_2("==", eq::<Instant>);
|
|
||||||
lib.set_fn_2("!=", ne::<Instant>);
|
|
||||||
|
|
||||||
#[cfg(not(feature = "no_float"))]
|
|
||||||
fn elapsed (timestamp: &mut Instant) -> Result<FLOAT, Box<EvalAltResult>> {
|
|
||||||
Ok(timestamp.elapsed().as_secs_f64())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "no_float")]
|
|
||||||
fn elapsed (timestamp: &mut Instant) -> Result<INT, Box<EvalAltResult>> {
|
|
||||||
let seconds = timestamp.elapsed().as_secs();
|
let seconds = timestamp.elapsed().as_secs();
|
||||||
|
|
||||||
#[cfg(not(feature = "unchecked"))]
|
#[cfg(not(feature = "unchecked"))]
|
||||||
@ -95,14 +67,73 @@ def_package!(crate:BasicTimePackage:"Basic timing utilities.", lib, {
|
|||||||
return EvalAltResult::ErrorArithmetic(
|
return EvalAltResult::ErrorArithmetic(
|
||||||
format!("Integer overflow for timestamp.elapsed: {}", seconds),
|
format!("Integer overflow for timestamp.elapsed: {}", seconds),
|
||||||
Position::none(),
|
Position::none(),
|
||||||
).into();
|
)
|
||||||
|
.into();
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(seconds as INT)
|
Ok((seconds as INT).into())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "no_float"))]
|
||||||
|
#[export_fn]
|
||||||
|
fn time_diff(ts1: Instant, ts2: Instant) -> FLOAT {
|
||||||
|
if ts2 > ts1 {
|
||||||
|
-(ts2 - ts1).as_secs_f64() as FLOAT
|
||||||
|
} else {
|
||||||
|
(ts1 - ts2).as_secs_f64() as FLOAT
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "no_float")]
|
||||||
|
#[export_fn(return_raw)]
|
||||||
|
fn time_diff(ts1: Instant, ts2: Instant) -> Result<Dynamic, Box<EvalAltResult>> {
|
||||||
|
if ts2 > ts1 {
|
||||||
|
let seconds = (ts2 - ts1).as_secs();
|
||||||
|
|
||||||
|
#[cfg(not(feature = "unchecked"))]
|
||||||
|
if seconds > (MAX_INT as u64) {
|
||||||
|
return EvalAltResult::ErrorArithmetic(
|
||||||
|
format!("Integer overflow for timestamp duration: -{}", seconds),
|
||||||
|
Position::none(),
|
||||||
|
)
|
||||||
|
.into();
|
||||||
}
|
}
|
||||||
|
|
||||||
lib.set_fn_1_mut("elapsed", elapsed);
|
Ok(-(seconds as INT).into())
|
||||||
|
} else {
|
||||||
|
let seconds = (ts1 - ts2).as_secs();
|
||||||
|
|
||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "unchecked"))]
|
||||||
lib.set_getter_fn("elapsed", elapsed);
|
if seconds > (MAX_INT as u64) {
|
||||||
});
|
return EvalAltResult::ErrorArithmetic(
|
||||||
|
format!("Integer overflow for timestamp duration: {}", seconds),
|
||||||
|
Position::none(),
|
||||||
|
)
|
||||||
|
.into();
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok((seconds as INT).into())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[export_module]
|
||||||
|
mod time_compare {
|
||||||
|
pub fn eq(x: Instant, y: Instant) -> bool {
|
||||||
|
x == y
|
||||||
|
}
|
||||||
|
pub fn ne(x: Instant, y: Instant) -> bool {
|
||||||
|
x != y
|
||||||
|
}
|
||||||
|
pub fn lt(x: Instant, y: Instant) -> bool {
|
||||||
|
x < y
|
||||||
|
}
|
||||||
|
pub fn lte(x: Instant, y: Instant) -> bool {
|
||||||
|
x <= y
|
||||||
|
}
|
||||||
|
pub fn gt(x: Instant, y: Instant) -> bool {
|
||||||
|
x > y
|
||||||
|
}
|
||||||
|
pub fn gte(x: Instant, y: Instant) -> bool {
|
||||||
|
x >= y
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -12,20 +12,42 @@ mod special_array_package {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[export_fn]
|
macro_rules! gen_unary_functions {
|
||||||
fn make_greeting(n: INT) -> String {
|
($op_name:ident = $op_fn:ident ( $($arg_type:ident),+ ) -> $return_type:ident) => {
|
||||||
format!("{} {}", n, if n > 1 { "kitties" } else { "kitty" }).into()
|
mod $op_name { $(
|
||||||
|
pub mod $arg_type {
|
||||||
|
use super::super::*;
|
||||||
|
|
||||||
|
#[export_fn]
|
||||||
|
pub fn single(x: $arg_type) -> $return_type {
|
||||||
|
super::super::$op_fn(x)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)* }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
macro_rules! reg_functions {
|
||||||
|
($mod_name:ident += $op_name:ident :: $func:ident ( $($arg_type:ident),+ )) => {
|
||||||
|
$(register_exported_fn!($mod_name, stringify!($op_name), $op_name::$arg_type::$func);)*
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn make_greeting<T: std::fmt::Display>(n: T) -> String {
|
||||||
|
format!("{} kitties", n)
|
||||||
|
}
|
||||||
|
|
||||||
|
gen_unary_functions!(greet = make_greeting(INT, bool, char) -> String);
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_plugins_package() -> Result<(), Box<EvalAltResult>> {
|
fn test_plugins_package() -> Result<(), Box<EvalAltResult>> {
|
||||||
let mut engine = Engine::new();
|
let mut engine = Engine::new();
|
||||||
|
|
||||||
let mut m = exported_module!(special_array_package);
|
let m = exported_module!(special_array_package);
|
||||||
set_exported_fn!(m, "greet", make_greeting);
|
|
||||||
|
|
||||||
engine.load_package(m);
|
engine.load_package(m);
|
||||||
|
|
||||||
|
reg_functions!(engine += greet::single(INT, bool, char));
|
||||||
|
|
||||||
assert_eq!(engine.eval::<INT>("let a = [1, 2, 3]; len(a, 2)")?, 6);
|
assert_eq!(engine.eval::<INT>("let a = [1, 2, 3]; len(a, 2)")?, 6);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
engine.eval::<String>("let a = [1, 2, 3]; greet(len(a, 2))")?,
|
engine.eval::<String>("let a = [1, 2, 3]; greet(len(a, 2))")?,
|
||||||
|
Loading…
Reference in New Issue
Block a user