From e1ce67adc257bb1350d2cc0d5d0c5734d786761b Mon Sep 17 00:00:00 2001 From: Stephen Chung Date: Sun, 27 Sep 2020 22:15:35 +0800 Subject: [PATCH] Add TimeStamp variant. --- src/any.rs | 58 +++++++++++++++++++----- src/packages/time_basic.rs | 91 ++++++++++++++++++++++++-------------- 2 files changed, 104 insertions(+), 45 deletions(-) diff --git a/src/any.rs b/src/any.rs index d9dada0d..7cc67870 100644 --- a/src/any.rs +++ b/src/any.rs @@ -159,6 +159,8 @@ pub enum Union { #[cfg(not(feature = "no_object"))] Map(Box), FnPtr(Box), + #[cfg(not(feature = "no_std"))] + TimeStamp(Box), Variant(Box>), @@ -313,6 +315,8 @@ impl Dynamic { #[cfg(not(feature = "no_object"))] Union::Map(_) => TypeId::of::(), Union::FnPtr(_) => TypeId::of::(), + #[cfg(not(feature = "no_std"))] + Union::TimeStamp(_) => TypeId::of::(), Union::Variant(value) => (***value).type_id(), @@ -345,9 +349,9 @@ impl Dynamic { #[cfg(not(feature = "no_object"))] Union::Map(_) => "map", Union::FnPtr(_) => "Fn", - #[cfg(not(feature = "no_std"))] - Union::Variant(value) if value.is::() => "timestamp", + Union::TimeStamp(_) => "timestamp", + Union::Variant(value) => (***value).type_name(), #[cfg(not(feature = "no_closure"))] @@ -375,10 +379,6 @@ pub(crate) fn map_std_type_name(name: &str) -> &str { } else if name == type_name::() { "Fn" } else { - #[cfg(not(feature = "no_std"))] - if name == type_name::() { - return "timestamp"; - } #[cfg(not(feature = "no_index"))] if name == type_name::() { return "array"; @@ -387,6 +387,10 @@ pub(crate) fn map_std_type_name(name: &str) -> &str { if name == type_name::() { return "map"; } + #[cfg(not(feature = "no_std"))] + if name == type_name::() { + return "timestamp"; + } name } @@ -410,9 +414,9 @@ impl fmt::Display for Dynamic { fmt::Debug::fmt(value, f) } Union::FnPtr(value) => fmt::Display::fmt(value, f), - #[cfg(not(feature = "no_std"))] - Union::Variant(value) if value.is::() => f.write_str(""), + Union::TimeStamp(_) => f.write_str(""), + Union::Variant(value) => f.write_str((*value).type_name()), #[cfg(not(feature = "no_closure"))] @@ -449,9 +453,9 @@ impl fmt::Debug for Dynamic { fmt::Debug::fmt(value, f) } Union::FnPtr(value) => fmt::Debug::fmt(value, f), - #[cfg(not(feature = "no_std"))] - Union::Variant(value) if value.is::() => write!(f, ""), + Union::TimeStamp(_) => write!(f, ""), + Union::Variant(value) => write!(f, "{}", (*value).type_name()), #[cfg(not(feature = "no_closure"))] @@ -485,6 +489,8 @@ impl Clone for Dynamic { #[cfg(not(feature = "no_object"))] Union::Map(ref value) => Self(Union::Map(value.clone())), Union::FnPtr(ref value) => Self(Union::FnPtr(value.clone())), + #[cfg(not(feature = "no_std"))] + Union::TimeStamp(ref value) => Self(Union::TimeStamp(value.clone())), Union::Variant(ref value) => (***value).clone_into_dynamic(), @@ -601,6 +607,14 @@ impl Dynamic { Err(val) => val, }; + #[cfg(not(feature = "no_std"))] + { + boxed = match unsafe_cast_box::<_, Instant>(boxed) { + Ok(timestamp) => return (*timestamp).into(), + Err(val) => val, + } + } + Self(Union::Variant(Box::new(boxed))) } @@ -738,6 +752,14 @@ impl Dynamic { }; } + #[cfg(not(feature = "no_std"))] + if TypeId::of::() == TypeId::of::() { + return match self.0 { + Union::TimeStamp(value) => unsafe_cast_box::<_, T>(value).ok().map(|v| *v), + _ => None, + }; + } + if TypeId::of::() == TypeId::of::<()>() { return match self.0 { Union::Unit(value) => unsafe_try_cast(value), @@ -993,6 +1015,13 @@ impl Dynamic { _ => None, }; } + #[cfg(not(feature = "no_std"))] + if TypeId::of::() == TypeId::of::() { + return match &self.0 { + Union::TimeStamp(value) => ::downcast_ref::(value.as_ref()), + _ => None, + }; + } if TypeId::of::() == TypeId::of::<()>() { return match &self.0 { Union::Unit(value) => ::downcast_ref::(value), @@ -1068,6 +1097,13 @@ impl Dynamic { _ => None, }; } + #[cfg(not(feature = "no_std"))] + if TypeId::of::() == TypeId::of::() { + return match &mut self.0 { + Union::TimeStamp(value) => ::downcast_mut::(value.as_mut()), + _ => None, + }; + } if TypeId::of::() == TypeId::of::<()>() { return match &mut self.0 { Union::Unit(value) => ::downcast_mut::(value), @@ -1273,6 +1309,6 @@ impl From> for Dynamic { impl From for Dynamic { #[inline(always)] fn from(value: Instant) -> Self { - Self(Union::Variant(Box::new(Box::new(value)))) + Self(Union::TimeStamp(Box::new(value))) } } diff --git a/src/packages/time_basic.rs b/src/packages/time_basic.rs index b6aabdd6..1fee278b 100644 --- a/src/packages/time_basic.rs +++ b/src/packages/time_basic.rs @@ -93,13 +93,10 @@ mod time_functions { #[cfg(not(feature = "no_float"))] pub mod float_functions { - #[rhai_fn(return_raw, name = "+")] - pub fn add(x: Instant, seconds: FLOAT) -> Result> { + fn add_impl(x: Instant, seconds: FLOAT) -> Result> { if seconds < 0.0 { - return subtract(x, -seconds); - } - - if cfg!(not(feature = "unchecked")) { + subtract_impl(x, -seconds) + } else if cfg!(not(feature = "unchecked")) { if seconds > (MAX_INT as FLOAT) { Err(make_arithmetic_err(format!( "Integer overflow for timestamp add: {}", @@ -113,20 +110,15 @@ mod time_functions { seconds )) }) - .map(Into::::into) } } else { - Ok((x + Duration::from_millis((seconds * 1000.0) as u64)).into()) + Ok(x + Duration::from_millis((seconds * 1000.0) as u64)) } } - - #[rhai_fn(return_raw, name = "-")] - pub fn subtract(x: Instant, seconds: FLOAT) -> Result> { + fn subtract_impl(x: Instant, seconds: FLOAT) -> Result> { if seconds < 0.0 { - return add(x, -seconds); - } - - if cfg!(not(feature = "unchecked")) { + add_impl(x, -seconds) + } else if cfg!(not(feature = "unchecked")) { if seconds > (MAX_INT as FLOAT) { Err(make_arithmetic_err(format!( "Integer overflow for timestamp add: {}", @@ -140,21 +132,39 @@ mod time_functions { seconds )) }) - .map(Into::::into) } } else { - Ok((x - Duration::from_millis((seconds * 1000.0) as u64)).into()) + Ok(x - Duration::from_millis((seconds * 1000.0) as u64)) } } + + #[rhai_fn(return_raw, name = "+")] + pub fn add(x: Instant, seconds: FLOAT) -> Result> { + add_impl(x, seconds).map(Into::::into) + } + #[rhai_fn(return_raw, name = "+=")] + pub fn add_assign(x: &mut Instant, seconds: FLOAT) -> Result> { + *x = add_impl(*x, seconds)?; + Ok(().into()) + } + #[rhai_fn(return_raw, name = "-")] + pub fn subtract(x: Instant, seconds: FLOAT) -> Result> { + subtract_impl(x, seconds).map(Into::::into) + } + #[rhai_fn(return_raw, name = "-=")] + pub fn subtract_assign( + x: &mut Instant, + seconds: FLOAT, + ) -> Result> { + *x = subtract_impl(*x, seconds)?; + Ok(().into()) + } } - #[rhai_fn(return_raw, name = "+")] - pub fn add(x: Instant, seconds: INT) -> Result> { + fn add_impl(x: Instant, seconds: INT) -> Result> { if seconds < 0 { - return subtract(x, -seconds); - } - - if cfg!(not(feature = "unchecked")) { + subtract_impl(x, -seconds) + } else if cfg!(not(feature = "unchecked")) { x.checked_add(Duration::from_secs(seconds as u64)) .ok_or_else(|| { make_arithmetic_err(format!( @@ -162,19 +172,14 @@ mod time_functions { seconds )) }) - .map(Into::::into) } else { - Ok((x + Duration::from_secs(seconds as u64)).into()) + Ok(x + Duration::from_secs(seconds as u64)) } } - - #[rhai_fn(return_raw, name = "-")] - pub fn subtract(x: Instant, seconds: INT) -> Result> { + fn subtract_impl(x: Instant, seconds: INT) -> Result> { if seconds < 0 { - return add(x, -seconds); - } - - if cfg!(not(feature = "unchecked")) { + add_impl(x, -seconds) + } else if cfg!(not(feature = "unchecked")) { x.checked_sub(Duration::from_secs(seconds as u64)) .ok_or_else(|| { make_arithmetic_err(format!( @@ -182,12 +187,30 @@ mod time_functions { seconds )) }) - .map(Into::::into) } else { - Ok((x - Duration::from_secs(seconds as u64)).into()) + Ok(x - Duration::from_secs(seconds as u64)) } } + #[rhai_fn(return_raw, name = "+")] + pub fn add(x: Instant, seconds: INT) -> Result> { + add_impl(x, seconds).map(Into::::into) + } + #[rhai_fn(return_raw, name = "+=")] + pub fn add_assign(x: &mut Instant, seconds: INT) -> Result> { + *x = add_impl(*x, seconds)?; + Ok(().into()) + } + #[rhai_fn(return_raw, name = "-")] + pub fn subtract(x: Instant, seconds: INT) -> Result> { + subtract_impl(x, seconds).map(Into::::into) + } + #[rhai_fn(return_raw, name = "-=")] + pub fn subtract_assign(x: &mut Instant, seconds: INT) -> Result> { + *x = subtract_impl(*x, seconds)?; + Ok(().into()) + } + #[rhai_fn(name = "==")] #[inline(always)] pub fn eq(x: Instant, y: Instant) -> bool {