From c40c0a0bc3c96612f69d8af27de4310f439de157 Mon Sep 17 00:00:00 2001 From: Stephen Chung Date: Wed, 22 Apr 2020 14:07:34 +0800 Subject: [PATCH] Add From> and From> for Dynamic. --- README.md | 27 +++++++++++++++++++-------- src/any.rs | 21 +++++++++++++++++++++ 2 files changed, 40 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 7cfdb6d4..b9eb1952 100644 --- a/README.md +++ b/README.md @@ -535,6 +535,16 @@ match item.type_name() { // 'type_name' returns the name } ``` +The following conversion traits are implemented for `Dynamic`: + +* `From` (`i32` if [`only_i32`]) +* `From` (if not [`no_float`]) +* `From` +* `From` +* `From` +* `From>` (into an [array]) +* `From>` (into an [object map]). + Value conversions ----------------- @@ -684,7 +694,7 @@ fn main() engine.register_result_fn("divide", safe_divide); if let Err(error) = engine.eval::("divide(40, 0)") { - println!("Error: {:?}", *error); // prints ErrorRuntime("Division by zero detected!", (1, 1)") + println!("Error: {:?}", *error); // prints ErrorRuntime("Division by zero detected!", (1, 1)") } } ``` @@ -1430,6 +1440,7 @@ engine.register_fn("push", |list: &mut Array, item: MyType| list.push(Box::new(i Object maps ----------- +[`Map`]: #object-maps [object map]: #object-maps [object maps]: #object-maps @@ -1630,13 +1641,13 @@ ts == 42; // false - types are not the same Boolean operators ----------------- -| Operator | Description | -| -------- | ------------------------------- | -| `!` | Boolean _Not_ | -| `&&` | Boolean _And_ (short-circuits) | -| `\|\|` | Boolean _Or_ (short-circuits) | -| `&` | Boolean _And_ (full evaluation) | -| `\|` | Boolean _Or_ (full evaluation) | +| Operator | Description | +| -------- | ------------------------------------- | +| `!` | Boolean _Not_ | +| `&&` | Boolean _And_ (short-circuits) | +| `\|\|` | Boolean _Or_ (short-circuits) | +| `&` | Boolean _And_ (doesn't short-circuit) | +| `\|` | Boolean _Or_ (doesn't short-circuit) | Double boolean operators `&&` and `||` _short-circuit_, meaning that the second operand will not be evaluated if the first one already proves the condition wrong. diff --git a/src/any.rs b/src/any.rs index ffa6fe18..f0f20938 100644 --- a/src/any.rs +++ b/src/any.rs @@ -9,6 +9,7 @@ use crate::parser::FLOAT; use crate::stdlib::{ any::{type_name, Any, TypeId}, boxed::Box, + collections::HashMap, fmt, string::String, }; @@ -65,6 +66,9 @@ impl Variant for T { } /// A trait to represent any type. +/// +/// `From<_>` is implemented for `i64` (`i32` if `only_i32`), `f64` (if not `no_float`), +/// `bool`, `String`, `char`, `Vec` (into `Array`) and `HashMap` (into `Map`). #[cfg(feature = "sync")] pub trait Variant: Any + Send + Sync { /// Convert this `Variant` trait object to `&dyn Any`. @@ -525,6 +529,23 @@ impl From for Dynamic { Self(Union::Str(Box::new(value))) } } +impl From> for Dynamic { + fn from(value: Vec) -> Self { + Self(Union::Array(Box::new( + value.into_iter().map(Dynamic::from).collect(), + ))) + } +} +impl From> for Dynamic { + fn from(value: HashMap) -> Self { + Self(Union::Map(Box::new( + value + .into_iter() + .map(|(k, v)| (k, Dynamic::from(v))) + .collect(), + ))) + } +} /// Private type which ensures that `rhai::Any` and `rhai::AnyExt` can only /// be implemented by this crate.