Add TimeStamp variant.

This commit is contained in:
Stephen Chung 2020-09-27 22:15:35 +08:00
parent 516f7b60d9
commit e1ce67adc2
2 changed files with 104 additions and 45 deletions

View File

@ -159,6 +159,8 @@ pub enum Union {
#[cfg(not(feature = "no_object"))] #[cfg(not(feature = "no_object"))]
Map(Box<Map>), Map(Box<Map>),
FnPtr(Box<FnPtr>), FnPtr(Box<FnPtr>),
#[cfg(not(feature = "no_std"))]
TimeStamp(Box<Instant>),
Variant(Box<Box<dyn Variant>>), Variant(Box<Box<dyn Variant>>),
@ -313,6 +315,8 @@ impl Dynamic {
#[cfg(not(feature = "no_object"))] #[cfg(not(feature = "no_object"))]
Union::Map(_) => TypeId::of::<Map>(), Union::Map(_) => TypeId::of::<Map>(),
Union::FnPtr(_) => TypeId::of::<FnPtr>(), Union::FnPtr(_) => TypeId::of::<FnPtr>(),
#[cfg(not(feature = "no_std"))]
Union::TimeStamp(_) => TypeId::of::<Instant>(),
Union::Variant(value) => (***value).type_id(), Union::Variant(value) => (***value).type_id(),
@ -345,9 +349,9 @@ impl Dynamic {
#[cfg(not(feature = "no_object"))] #[cfg(not(feature = "no_object"))]
Union::Map(_) => "map", Union::Map(_) => "map",
Union::FnPtr(_) => "Fn", Union::FnPtr(_) => "Fn",
#[cfg(not(feature = "no_std"))] #[cfg(not(feature = "no_std"))]
Union::Variant(value) if value.is::<Instant>() => "timestamp", Union::TimeStamp(_) => "timestamp",
Union::Variant(value) => (***value).type_name(), Union::Variant(value) => (***value).type_name(),
#[cfg(not(feature = "no_closure"))] #[cfg(not(feature = "no_closure"))]
@ -375,10 +379,6 @@ pub(crate) fn map_std_type_name(name: &str) -> &str {
} else if name == type_name::<FnPtr>() { } else if name == type_name::<FnPtr>() {
"Fn" "Fn"
} else { } else {
#[cfg(not(feature = "no_std"))]
if name == type_name::<Instant>() {
return "timestamp";
}
#[cfg(not(feature = "no_index"))] #[cfg(not(feature = "no_index"))]
if name == type_name::<Array>() { if name == type_name::<Array>() {
return "array"; return "array";
@ -387,6 +387,10 @@ pub(crate) fn map_std_type_name(name: &str) -> &str {
if name == type_name::<Map>() { if name == type_name::<Map>() {
return "map"; return "map";
} }
#[cfg(not(feature = "no_std"))]
if name == type_name::<Instant>() {
return "timestamp";
}
name name
} }
@ -410,9 +414,9 @@ impl fmt::Display for Dynamic {
fmt::Debug::fmt(value, f) fmt::Debug::fmt(value, f)
} }
Union::FnPtr(value) => fmt::Display::fmt(value, f), Union::FnPtr(value) => fmt::Display::fmt(value, f),
#[cfg(not(feature = "no_std"))] #[cfg(not(feature = "no_std"))]
Union::Variant(value) if value.is::<Instant>() => f.write_str("<timestamp>"), Union::TimeStamp(_) => f.write_str("<timestamp>"),
Union::Variant(value) => f.write_str((*value).type_name()), Union::Variant(value) => f.write_str((*value).type_name()),
#[cfg(not(feature = "no_closure"))] #[cfg(not(feature = "no_closure"))]
@ -449,9 +453,9 @@ impl fmt::Debug for Dynamic {
fmt::Debug::fmt(value, f) fmt::Debug::fmt(value, f)
} }
Union::FnPtr(value) => fmt::Debug::fmt(value, f), Union::FnPtr(value) => fmt::Debug::fmt(value, f),
#[cfg(not(feature = "no_std"))] #[cfg(not(feature = "no_std"))]
Union::Variant(value) if value.is::<Instant>() => write!(f, "<timestamp>"), Union::TimeStamp(_) => write!(f, "<timestamp>"),
Union::Variant(value) => write!(f, "{}", (*value).type_name()), Union::Variant(value) => write!(f, "{}", (*value).type_name()),
#[cfg(not(feature = "no_closure"))] #[cfg(not(feature = "no_closure"))]
@ -485,6 +489,8 @@ impl Clone for Dynamic {
#[cfg(not(feature = "no_object"))] #[cfg(not(feature = "no_object"))]
Union::Map(ref value) => Self(Union::Map(value.clone())), Union::Map(ref value) => Self(Union::Map(value.clone())),
Union::FnPtr(ref value) => Self(Union::FnPtr(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(), Union::Variant(ref value) => (***value).clone_into_dynamic(),
@ -601,6 +607,14 @@ impl Dynamic {
Err(val) => val, 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))) Self(Union::Variant(Box::new(boxed)))
} }
@ -738,6 +752,14 @@ impl Dynamic {
}; };
} }
#[cfg(not(feature = "no_std"))]
if TypeId::of::<T>() == TypeId::of::<Instant>() {
return match self.0 {
Union::TimeStamp(value) => unsafe_cast_box::<_, T>(value).ok().map(|v| *v),
_ => None,
};
}
if TypeId::of::<T>() == 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),
@ -993,6 +1015,13 @@ impl Dynamic {
_ => None, _ => None,
}; };
} }
#[cfg(not(feature = "no_std"))]
if TypeId::of::<T>() == TypeId::of::<Instant>() {
return match &self.0 {
Union::TimeStamp(value) => <dyn Any>::downcast_ref::<T>(value.as_ref()),
_ => None,
};
}
if TypeId::of::<T>() == 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),
@ -1068,6 +1097,13 @@ impl Dynamic {
_ => None, _ => None,
}; };
} }
#[cfg(not(feature = "no_std"))]
if TypeId::of::<T>() == TypeId::of::<Instant>() {
return match &mut self.0 {
Union::TimeStamp(value) => <dyn Any>::downcast_mut::<T>(value.as_mut()),
_ => None,
};
}
if TypeId::of::<T>() == 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),
@ -1273,6 +1309,6 @@ impl From<Box<FnPtr>> for Dynamic {
impl From<Instant> for Dynamic { impl From<Instant> for Dynamic {
#[inline(always)] #[inline(always)]
fn from(value: Instant) -> Self { fn from(value: Instant) -> Self {
Self(Union::Variant(Box::new(Box::new(value)))) Self(Union::TimeStamp(Box::new(value)))
} }
} }

View File

@ -93,13 +93,10 @@ mod time_functions {
#[cfg(not(feature = "no_float"))] #[cfg(not(feature = "no_float"))]
pub mod float_functions { pub mod float_functions {
#[rhai_fn(return_raw, name = "+")] fn add_impl(x: Instant, seconds: FLOAT) -> Result<Instant, Box<EvalAltResult>> {
pub fn add(x: Instant, seconds: FLOAT) -> Result<Dynamic, Box<EvalAltResult>> {
if seconds < 0.0 { if seconds < 0.0 {
return subtract(x, -seconds); subtract_impl(x, -seconds)
} } else if cfg!(not(feature = "unchecked")) {
if cfg!(not(feature = "unchecked")) {
if seconds > (MAX_INT as FLOAT) { if seconds > (MAX_INT as FLOAT) {
Err(make_arithmetic_err(format!( Err(make_arithmetic_err(format!(
"Integer overflow for timestamp add: {}", "Integer overflow for timestamp add: {}",
@ -113,20 +110,15 @@ mod time_functions {
seconds seconds
)) ))
}) })
.map(Into::<Dynamic>::into)
} }
} else { } else {
Ok((x + Duration::from_millis((seconds * 1000.0) as u64)).into()) Ok(x + Duration::from_millis((seconds * 1000.0) as u64))
} }
} }
fn subtract_impl(x: Instant, seconds: FLOAT) -> Result<Instant, Box<EvalAltResult>> {
#[rhai_fn(return_raw, name = "-")]
pub fn subtract(x: Instant, seconds: FLOAT) -> Result<Dynamic, Box<EvalAltResult>> {
if seconds < 0.0 { if seconds < 0.0 {
return add(x, -seconds); add_impl(x, -seconds)
} } else if cfg!(not(feature = "unchecked")) {
if cfg!(not(feature = "unchecked")) {
if seconds > (MAX_INT as FLOAT) { if seconds > (MAX_INT as FLOAT) {
Err(make_arithmetic_err(format!( Err(make_arithmetic_err(format!(
"Integer overflow for timestamp add: {}", "Integer overflow for timestamp add: {}",
@ -140,21 +132,39 @@ mod time_functions {
seconds seconds
)) ))
}) })
.map(Into::<Dynamic>::into)
} }
} else { } 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<Dynamic, Box<EvalAltResult>> {
add_impl(x, seconds).map(Into::<Dynamic>::into)
}
#[rhai_fn(return_raw, name = "+=")]
pub fn add_assign(x: &mut Instant, seconds: FLOAT) -> Result<Dynamic, Box<EvalAltResult>> {
*x = add_impl(*x, seconds)?;
Ok(().into())
}
#[rhai_fn(return_raw, name = "-")]
pub fn subtract(x: Instant, seconds: FLOAT) -> Result<Dynamic, Box<EvalAltResult>> {
subtract_impl(x, seconds).map(Into::<Dynamic>::into)
}
#[rhai_fn(return_raw, name = "-=")]
pub fn subtract_assign(
x: &mut Instant,
seconds: FLOAT,
) -> Result<Dynamic, Box<EvalAltResult>> {
*x = subtract_impl(*x, seconds)?;
Ok(().into())
}
} }
#[rhai_fn(return_raw, name = "+")] fn add_impl(x: Instant, seconds: INT) -> Result<Instant, Box<EvalAltResult>> {
pub fn add(x: Instant, seconds: INT) -> Result<Dynamic, Box<EvalAltResult>> {
if seconds < 0 { if seconds < 0 {
return subtract(x, -seconds); subtract_impl(x, -seconds)
} } else if cfg!(not(feature = "unchecked")) {
if cfg!(not(feature = "unchecked")) {
x.checked_add(Duration::from_secs(seconds as u64)) x.checked_add(Duration::from_secs(seconds as u64))
.ok_or_else(|| { .ok_or_else(|| {
make_arithmetic_err(format!( make_arithmetic_err(format!(
@ -162,19 +172,14 @@ mod time_functions {
seconds seconds
)) ))
}) })
.map(Into::<Dynamic>::into)
} else { } else {
Ok((x + Duration::from_secs(seconds as u64)).into()) Ok(x + Duration::from_secs(seconds as u64))
} }
} }
fn subtract_impl(x: Instant, seconds: INT) -> Result<Instant, Box<EvalAltResult>> {
#[rhai_fn(return_raw, name = "-")]
pub fn subtract(x: Instant, seconds: INT) -> Result<Dynamic, Box<EvalAltResult>> {
if seconds < 0 { if seconds < 0 {
return add(x, -seconds); add_impl(x, -seconds)
} } else if cfg!(not(feature = "unchecked")) {
if cfg!(not(feature = "unchecked")) {
x.checked_sub(Duration::from_secs(seconds as u64)) x.checked_sub(Duration::from_secs(seconds as u64))
.ok_or_else(|| { .ok_or_else(|| {
make_arithmetic_err(format!( make_arithmetic_err(format!(
@ -182,12 +187,30 @@ mod time_functions {
seconds seconds
)) ))
}) })
.map(Into::<Dynamic>::into)
} else { } 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<Dynamic, Box<EvalAltResult>> {
add_impl(x, seconds).map(Into::<Dynamic>::into)
}
#[rhai_fn(return_raw, name = "+=")]
pub fn add_assign(x: &mut Instant, seconds: INT) -> Result<Dynamic, Box<EvalAltResult>> {
*x = add_impl(*x, seconds)?;
Ok(().into())
}
#[rhai_fn(return_raw, name = "-")]
pub fn subtract(x: Instant, seconds: INT) -> Result<Dynamic, Box<EvalAltResult>> {
subtract_impl(x, seconds).map(Into::<Dynamic>::into)
}
#[rhai_fn(return_raw, name = "-=")]
pub fn subtract_assign(x: &mut Instant, seconds: INT) -> Result<Dynamic, Box<EvalAltResult>> {
*x = subtract_impl(*x, seconds)?;
Ok(().into())
}
#[rhai_fn(name = "==")] #[rhai_fn(name = "==")]
#[inline(always)] #[inline(always)]
pub fn eq(x: Instant, y: Instant) -> bool { pub fn eq(x: Instant, y: Instant) -> bool {