Change object maps to #{ ... }

This commit is contained in:
Stephen Chung 2020-03-30 17:40:26 +08:00
parent ee18f047b4
commit 01c0b51017
5 changed files with 39 additions and 36 deletions

View File

@ -1047,7 +1047,7 @@ Object maps
----------- -----------
Object maps are dictionaries. Properties of any type (`Dynamic`) can be freely added and retrieved. Object maps are dictionaries. Properties of any type (`Dynamic`) can be freely added and retrieved.
Object map literals are built within braces '`${`' ... '`}`' (_name_ `:` _value_ syntax similar to Rust) Object map literals are built within braces '`#{`' ... '`}`' (_name_ `:` _value_ syntax similar to Rust)
and separated by commas '`,`'. The property _name_ can be a simple variable name following the same and separated by commas '`,`'. The property _name_ can be a simple variable name following the same
naming rules as [variables], or an arbitrary string literal. naming rules as [variables], or an arbitrary string literal.
@ -1074,7 +1074,7 @@ The following functions (defined in the standard library but excluded if [`no_st
Examples: Examples:
```rust ```rust
let y = ${ // object map literal with 3 properties let y = #{ // object map literal with 3 properties
a: 1, a: 1,
bar: "hello", bar: "hello",
"baz!$@": 123.456, // like JS, you can use any string as property names... "baz!$@": 123.456, // like JS, you can use any string as property names...
@ -1095,11 +1095,11 @@ ts.obj = y; // object maps can be assigned completely (by value copy
let foo = ts.list.a; let foo = ts.list.a;
foo == 42; foo == 42;
let foo = ${ a:1, b:2, c:3 }["a"]; let foo = #{ a:1, b:2, c:3 }["a"];
foo == 1; foo == 1;
fn abc() { fn abc() {
${ a:1, b:2, c:3 } // a function returning an object map #{ a:1, b:2, c:3 } // a function returning an object map
} }
let foo = abc().b; let foo = abc().b;

View File

@ -610,8 +610,8 @@ impl Engine<'_> {
#[cfg(not(feature = "no_object"))] #[cfg(not(feature = "no_object"))]
{ {
self.register_fn("print", |x: &mut Map| -> String { format!("${:?}", x) }); self.register_fn("print", |x: &mut Map| -> String { format!("#{:?}", x) });
self.register_fn("debug", |x: &mut Map| -> String { format!("${:?}", x) }); self.register_fn("debug", |x: &mut Map| -> String { format!("#{:?}", x) });
} }
} }

View File

@ -368,7 +368,7 @@ pub enum Expr {
/// [ expr, ... ] /// [ expr, ... ]
Array(Vec<Expr>, Position), Array(Vec<Expr>, Position),
#[cfg(not(feature = "no_object"))] #[cfg(not(feature = "no_object"))]
/// ${ name:expr, ... } /// #{ name:expr, ... }
Map(Vec<(String, Expr, Position)>, Position), Map(Vec<(String, Expr, Position)>, Position),
/// lhs && rhs /// lhs && rhs
And(Box<Expr>, Box<Expr>), And(Box<Expr>, Box<Expr>),
@ -627,7 +627,7 @@ impl Token {
Comma => ",", Comma => ",",
Period => ".", Period => ".",
#[cfg(not(feature = "no_object"))] #[cfg(not(feature = "no_object"))]
MapStart => "${", MapStart => "#{",
Equals => "=", Equals => "=",
True => "true", True => "true",
False => "false", False => "false",
@ -1159,7 +1159,7 @@ impl<'a> TokenIterator<'a> {
// Map literal // Map literal
#[cfg(not(feature = "no_object"))] #[cfg(not(feature = "no_object"))]
('$', '{') => { ('#', '{') => {
self.eat_next(); self.eat_next();
return Some((Token::MapStart, pos)); return Some((Token::MapStart, pos));
} }

View File

@ -1,31 +1,34 @@
#![cfg(not(feature = "no_object"))] #![cfg(not(feature = "no_object"))]
#![cfg(not(feature = "no_index"))]
use rhai::{AnyExt, Dynamic, Engine, EvalAltResult, Map, RegisterFn, INT}; use rhai::{AnyExt, Engine, EvalAltResult, Map, INT};
#[test] #[test]
fn test_map_indexing() -> Result<(), EvalAltResult> { fn test_map_indexing() -> Result<(), EvalAltResult> {
let mut engine = Engine::new(); let mut engine = Engine::new();
#[cfg(not(feature = "no_index"))]
assert_eq!( assert_eq!(
engine.eval::<INT>(r#"let x = ${a: 1, b: 2, c: 3}; x["b"]"#)?, engine.eval::<INT>(r#"let x = #{a: 1, b: 2, c: 3}; x["b"]"#)?,
2 2
); );
assert_eq!( assert_eq!(
engine.eval::<INT>("let y = ${a: 1, b: 2, c: 3}; y.a = 5; y.a")?, engine.eval::<INT>("let y = #{a: 1, b: 2, c: 3}; y.a = 5; y.a")?,
5 5
); );
#[cfg(not(feature = "no_index"))]
assert_eq!( assert_eq!(
engine.eval::<char>( engine.eval::<char>(
r#" r#"
let y = ${d: 1, "e": ${a: 42, b: 88, "": "93"}, " 123 xyz": 9}; let y = #{d: 1, "e": #{a: 42, b: 88, "": "hello"}, " 123 xyz": 9};
y.e[""][1] y.e[""][4]
"# "#
)?, )?,
'3' 'o'
); );
engine.eval::<()>("let y = ${a: 1, b: 2, c: 3}; y.z")?; engine.eval::<()>("let y = #{a: 1, b: 2, c: 3}; y.z")?;
Ok(()) Ok(())
} }
@ -34,14 +37,14 @@ fn test_map_indexing() -> Result<(), EvalAltResult> {
fn test_map_assign() -> Result<(), EvalAltResult> { fn test_map_assign() -> Result<(), EvalAltResult> {
let mut engine = Engine::new(); let mut engine = Engine::new();
let mut x = engine.eval::<Map>("let x = ${a: 1, b: true, c: \"3\"}; x")?; let x = engine.eval::<Map>(r#"let x = #{a: 1, b: true, "c#": "hello"}; x"#)?;
let box_a = x.remove("a").unwrap(); let a = x.get("a").cloned().unwrap();
let box_b = x.remove("b").unwrap(); let b = x.get("b").cloned().unwrap();
let box_c = x.remove("c").unwrap(); let c = x.get("c#").cloned().unwrap();
assert_eq!(*box_a.downcast::<INT>().unwrap(), 1); assert_eq!(*a.downcast::<INT>().unwrap(), 1);
assert_eq!(*box_b.downcast::<bool>().unwrap(), true); assert_eq!(*b.downcast::<bool>().unwrap(), true);
assert_eq!(*box_c.downcast::<String>().unwrap(), "3"); assert_eq!(*c.downcast::<String>().unwrap(), "hello");
Ok(()) Ok(())
} }
@ -50,14 +53,14 @@ fn test_map_assign() -> Result<(), EvalAltResult> {
fn test_map_return() -> Result<(), EvalAltResult> { fn test_map_return() -> Result<(), EvalAltResult> {
let mut engine = Engine::new(); let mut engine = Engine::new();
let mut x = engine.eval::<Map>("${a: 1, b: true, c: \"3\"}")?; let x = engine.eval::<Map>(r#"#{a: 1, b: true, c: "hello"}"#)?;
let box_a = x.remove("a").unwrap(); let a = x.get("a").cloned().unwrap();
let box_b = x.remove("b").unwrap(); let b = x.get("b").cloned().unwrap();
let box_c = x.remove("c").unwrap(); let c = x.get("c").cloned().unwrap();
assert_eq!(*box_a.downcast::<INT>().unwrap(), 1); assert_eq!(*a.downcast::<INT>().unwrap(), 1);
assert_eq!(*box_b.downcast::<bool>().unwrap(), true); assert_eq!(*b.downcast::<bool>().unwrap(), true);
assert_eq!(*box_c.downcast::<String>().unwrap(), "3".to_string()); assert_eq!(*c.downcast::<String>().unwrap(), "hello");
Ok(()) Ok(())
} }

View File

@ -24,11 +24,11 @@ fn test_type_of() -> Result<(), EvalAltResult> {
"array" "array"
); );
// #[cfg(not(feature = "no_object"))] #[cfg(not(feature = "no_object"))]
// assert_eq!( assert_eq!(
// engine.eval::<String>(r#"type_of(${a:true, "":2, "z":"hello"})"#)?, engine.eval::<String>(r#"type_of(#{a:true, "":2, "z":"hello"})"#)?,
// "map" "map"
// ); );
#[cfg(not(feature = "no_object"))] #[cfg(not(feature = "no_object"))]
{ {