Skip to content

Commit

Permalink
New as_XXX_ref API for Dynamic
Browse files Browse the repository at this point in the history
  • Loading branch information
schungx committed Jul 26, 2024
1 parent 60e76b5 commit e343641
Show file tree
Hide file tree
Showing 11 changed files with 256 additions and 84 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ Bug fixes
Enhancements
------------

* New `as_immutable_string_ref`, `as_array_ref`, `as_blob_ref`, `as_map_ref` plus their `_mut` variants for `Dynamic`.
* The `break`, `return` and `throw` statements can now be simply used as `switch` case statement expressions. Previously it is required that the statement be wrapped in a block.


Expand Down
2 changes: 1 addition & 1 deletion src/api/json.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ impl Engine {
/// assert_eq!(map["b"].as_int().expect("b should exist"), 42);
/// assert_eq!(map["d"].as_unit().expect("d should exist"), ());
///
/// let c = map["c"].read_lock::<Map>().expect("c should exist");
/// let c = map["c"].as_map().expect("c should exist");
/// assert_eq!(c["x"].as_bool().expect("x should be bool"), false);

Check failure on line 56 in src/api/json.rs

View workflow job for this annotation

GitHub Actions / Build (ubuntu-latest, --features testing-environ,sync,no_time,no_function,no_float,no_position,no...

no method named `as_map` found for struct `Dynamic` in the current scope

Check failure on line 56 in src/api/json.rs

View workflow job for this annotation

GitHub Actions / Build (ubuntu-latest, --features testing-environ,no_function,serde,metadata,internals,debugging, ...

no method named `as_map` found for struct `Dynamic` in the current scope

Check failure on line 56 in src/api/json.rs

View workflow job for this annotation

GitHub Actions / Build (ubuntu-latest, --features testing-environ,no_index,serde,metadata,internals,debugging, sta...

no method named `as_map` found for struct `Dynamic` in the current scope

Check failure on line 56 in src/api/json.rs

View workflow job for this annotation

GitHub Actions / Build (ubuntu-latest, --features testing-environ,no_float,serde,metadata,internals,debugging, sta...

no method named `as_map` found for struct `Dynamic` in the current scope

Check failure on line 56 in src/api/json.rs

View workflow job for this annotation

GitHub Actions / Build (ubuntu-latest, --features testing-environ,no_module,serde,metadata,internals,debugging, st...

no method named `as_map` found for struct `Dynamic` in the current scope

Check failure on line 56 in src/api/json.rs

View workflow job for this annotation

GitHub Actions / Build (ubuntu-latest, --features testing-environ,no_optimize,serde,metadata,internals,debugging, ...

no method named `as_map` found for struct `Dynamic` in the current scope

Check failure on line 56 in src/api/json.rs

View workflow job for this annotation

GitHub Actions / Build (ubuntu-latest, --features testing-environ,no_closure,serde,metadata,internals,debugging, s...

no method named `as_map` found for struct `Dynamic` in the current scope

Check failure on line 56 in src/api/json.rs

View workflow job for this annotation

GitHub Actions / Build (ubuntu-latest, --features testing-environ,only_i64,serde,metadata,internals,debugging, sta...

no method named `as_map` found for struct `Dynamic` in the current scope

Check failure on line 56 in src/api/json.rs

View workflow job for this annotation

GitHub Actions / Build (ubuntu-latest, --features testing-environ,no_time,serde,metadata,internals,debugging, stab...

no method named `as_map` found for struct `Dynamic` in the current scope

Check failure on line 56 in src/api/json.rs

View workflow job for this annotation

GitHub Actions / Build (ubuntu-latest, --features testing-environ,metadata, stable, false)

no method named `as_map` found for struct `Dynamic` in the current scope

Check failure on line 56 in src/api/json.rs

View workflow job for this annotation

GitHub Actions / Build (ubuntu-latest, --features testing-environ,f32_float,serde,metadata,internals,debugging, st...

no method named `as_map` found for struct `Dynamic` in the current scope

Check failure on line 56 in src/api/json.rs

View workflow job for this annotation

GitHub Actions / Build (ubuntu-latest, --features testing-environ,no_custom_syntax,serde,metadata,internals,debugg...

no method named `as_map` found for struct `Dynamic` in the current scope

Check failure on line 56 in src/api/json.rs

View workflow job for this annotation

GitHub Actions / Build (ubuntu-latest, --features testing-environ,no_position,serde,metadata,internals,debugging, ...

no method named `as_map` found for struct `Dynamic` in the current scope

Check failure on line 56 in src/api/json.rs

View workflow job for this annotation

GitHub Actions / Build (ubuntu-latest, --features testing-environ,sync,serde,metadata,internals,debugging, stable,...

no method named `as_map` found for struct `Dynamic` in the current scope

Check failure on line 56 in src/api/json.rs

View workflow job for this annotation

GitHub Actions / Build (ubuntu-latest, --features testing-environ,unchecked,serde,metadata,internals,debugging, st...

no method named `as_map` found for struct `Dynamic` in the current scope

Check failure on line 56 in src/api/json.rs

View workflow job for this annotation

GitHub Actions / Build (ubuntu-latest, --features testing-environ,decimal,serde,metadata,internals,debugging, stab...

no method named `as_map` found for struct `Dynamic` in the current scope
/// assert_eq!(c["y"].as_bool().expect("y should be bool"), true);
/// assert_eq!(c["z"].as_char().expect("z should be char"), '$');
Expand Down
4 changes: 2 additions & 2 deletions src/bin/rhai-dbg.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use rhai::debugger::{BreakPoint, DebuggerCommand, DebuggerEvent};
use rhai::{Dynamic, Engine, EvalAltResult, ImmutableString, Position, Scope, INT};
use rhai::{Dynamic, Engine, EvalAltResult, Position, Scope, INT};

use std::{
env,
Expand Down Expand Up @@ -63,7 +63,7 @@ fn print_current_source(
.global_runtime_state_mut()
.debugger_mut()
.state_mut()
.write_lock::<ImmutableString>()
.as_immutable_string_ref_mut()
.unwrap();
let src = source.unwrap_or("");
if src != current_source {
Expand Down
53 changes: 24 additions & 29 deletions src/func/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -236,8 +236,8 @@ pub fn get_builtin_binary_op_fn(op: &Token, x: &Dynamic, y: &Dynamic) -> Option<
return match op {
Plus => Some((
|_ctx, args| {
let s1 = &*args[0].read_lock::<ImmutableString>().unwrap();
let s2 = &*args[1].read_lock::<ImmutableString>().unwrap();
let s1 = &*args[0].as_immutable_string_ref().unwrap();
let s2 = &*args[1].as_immutable_string_ref().unwrap();

#[cfg(not(feature = "unchecked"))]
_ctx.unwrap()
Expand Down Expand Up @@ -294,11 +294,11 @@ pub fn get_builtin_binary_op_fn(op: &Token, x: &Dynamic, y: &Dynamic) -> Option<
return match op {
Plus => Some((
|_ctx, args| {
let b2 = &*args[1].read_lock::<Blob>().unwrap();
let b2 = &*args[1].as_blob_ref().unwrap();
if b2.is_empty() {
return Ok(args[0].flatten_clone());
}
let b1 = &*args[0].read_lock::<Blob>().unwrap();
let b1 = &*args[0].as_blob_ref().unwrap();
if b1.is_empty() {
return Ok(args[1].flatten_clone());
}
Expand Down Expand Up @@ -475,7 +475,7 @@ pub fn get_builtin_binary_op_fn(op: &Token, x: &Dynamic, y: &Dynamic) -> Option<
if (type1, type2) == (TypeId::of::<char>(), TypeId::of::<ImmutableString>()) {
fn get_s1s2(args: &FnCallArgs) -> ([Option<char>; 2], [Option<char>; 2]) {
let x = args[0].as_char().unwrap();
let y = &*args[1].read_lock::<ImmutableString>().unwrap();
let y = &*args[1].as_immutable_string_ref().unwrap();
let s1 = [Some(x), None];
let mut y = y.chars();
let s2 = [y.next(), y.next()];
Expand All @@ -486,7 +486,7 @@ pub fn get_builtin_binary_op_fn(op: &Token, x: &Dynamic, y: &Dynamic) -> Option<
Plus => Some((
|_ctx, args| {
let x = args[0].as_char().unwrap();
let y = &*args[1].read_lock::<ImmutableString>().unwrap();
let y = &*args[1].as_immutable_string_ref().unwrap();

let mut result = SmartString::new_const();
result.push(x);
Expand All @@ -511,7 +511,7 @@ pub fn get_builtin_binary_op_fn(op: &Token, x: &Dynamic, y: &Dynamic) -> Option<
// string op char
if (type1, type2) == (TypeId::of::<ImmutableString>(), TypeId::of::<char>()) {
fn get_s1s2(args: &FnCallArgs) -> ([Option<char>; 2], [Option<char>; 2]) {
let x = &*args[0].read_lock::<ImmutableString>().unwrap();
let x = &*args[0].as_immutable_string_ref().unwrap();
let y = args[1].as_char().unwrap();
let mut x = x.chars();
let s1 = [x.next(), x.next()];
Expand All @@ -522,7 +522,7 @@ pub fn get_builtin_binary_op_fn(op: &Token, x: &Dynamic, y: &Dynamic) -> Option<
return match op {
Plus => Some((
|_ctx, args| {
let x = &*args[0].read_lock::<ImmutableString>().unwrap();
let x = &*args[0].as_immutable_string_ref().unwrap();
let y = args[1].as_char().unwrap();
let result = x + y;

Expand All @@ -535,7 +535,7 @@ pub fn get_builtin_binary_op_fn(op: &Token, x: &Dynamic, y: &Dynamic) -> Option<
)),
Minus => Some((
|_, args| {
let x = &*args[0].read_lock::<ImmutableString>().unwrap();
let x = &*args[0].as_immutable_string_ref().unwrap();
let y = args[1].as_char().unwrap();
Ok((x - y).into())
},
Expand Down Expand Up @@ -576,13 +576,11 @@ pub fn get_builtin_binary_op_fn(op: &Token, x: &Dynamic, y: &Dynamic) -> Option<
// blob
#[cfg(not(feature = "no_index"))]
if type1 == TypeId::of::<crate::Blob>() {
use crate::Blob;

if type2 == TypeId::of::<char>() {
return match op {
Plus => Some((
|_ctx, args| {
let mut blob = args[0].read_lock::<Blob>().unwrap().clone();
let mut blob = args[0].as_blob_ref().unwrap().clone();
let mut buf = [0_u8; 4];
let x = args[1].as_char().unwrap().encode_utf8(&mut buf);

Expand Down Expand Up @@ -794,8 +792,8 @@ pub fn get_builtin_op_assignment_fn(op: &Token, x: &Dynamic, y: &Dynamic) -> Opt
PlusAssign => Some((
|_ctx, args| {
let (first, second) = args.split_first_mut().unwrap();
let x = &mut *first.write_lock::<ImmutableString>().unwrap();
let y = &*second[0].read_lock::<ImmutableString>().unwrap();
let x = &mut *first.as_immutable_string_ref_mut().unwrap();
let y = &*second[0].as_immutable_string_ref().unwrap();

#[cfg(not(feature = "unchecked"))]
if !x.is_empty() && !y.is_empty() {
Expand All @@ -812,8 +810,8 @@ pub fn get_builtin_op_assignment_fn(op: &Token, x: &Dynamic, y: &Dynamic) -> Opt
MinusAssign => Some((
|_, args| {
let (first, second) = args.split_first_mut().unwrap();
let x = &mut *first.write_lock::<ImmutableString>().unwrap();
let y = &*second[0].read_lock::<ImmutableString>().unwrap();
let x = &mut *first.as_immutable_string_ref_mut().unwrap();
let y = &*second[0].as_immutable_string_ref().unwrap();
*x -= y;
Ok(Dynamic::UNIT)
},
Expand All @@ -827,7 +825,6 @@ pub fn get_builtin_op_assignment_fn(op: &Token, x: &Dynamic, y: &Dynamic) -> Opt
if type1 == TypeId::of::<crate::Array>() {
#[allow(clippy::wildcard_imports)]
use crate::packages::array_basic::array_functions::*;
use crate::Array;

return match op {
PlusAssign => Some((
Expand All @@ -839,14 +836,14 @@ pub fn get_builtin_op_assignment_fn(op: &Token, x: &Dynamic, y: &Dynamic) -> Opt
}

#[cfg(not(feature = "unchecked"))]
if !args[0].read_lock::<Array>().unwrap().is_empty() {
if !args[0].as_array_ref().unwrap().is_empty() {
_ctx.unwrap().engine().check_data_size(
&*args[0].read_lock().unwrap(),
crate::Position::NONE,
)?;
}

let array = &mut *args[0].write_lock::<Array>().unwrap();
let array = &mut *args[0].as_array_ref_mut().unwrap();

append(array, x);

Expand All @@ -862,13 +859,12 @@ pub fn get_builtin_op_assignment_fn(op: &Token, x: &Dynamic, y: &Dynamic) -> Opt
if type1 == TypeId::of::<crate::Blob>() {
#[allow(clippy::wildcard_imports)]
use crate::packages::blob_basic::blob_functions::*;
use crate::Blob;

return match op {
PlusAssign => Some((
|_ctx, args| {
let blob2 = args[1].take().into_blob().unwrap();
let blob1 = &mut *args[0].write_lock::<Blob>().unwrap();
let blob1 = &mut *args[0].as_blob_ref_mut().unwrap();

#[cfg(not(feature = "unchecked"))]
_ctx.unwrap()
Expand Down Expand Up @@ -958,7 +954,7 @@ pub fn get_builtin_op_assignment_fn(op: &Token, x: &Dynamic, y: &Dynamic) -> Opt
|_ctx, args| {
let mut buf = [0_u8; 4];
let ch = &*args[1].as_char().unwrap().encode_utf8(&mut buf);
let mut x = args[0].write_lock::<ImmutableString>().unwrap();
let mut x = args[0].as_immutable_string_ref_mut().unwrap();

#[cfg(not(feature = "unchecked"))]
_ctx.unwrap()
Expand All @@ -981,7 +977,7 @@ pub fn get_builtin_op_assignment_fn(op: &Token, x: &Dynamic, y: &Dynamic) -> Opt
PlusAssign => Some((
|_ctx, args| {
let ch = {
let s = &*args[1].read_lock::<ImmutableString>().unwrap();
let s = &*args[1].as_immutable_string_ref().unwrap();

if s.is_empty() {
return Ok(Dynamic::UNIT);
Expand Down Expand Up @@ -1013,14 +1009,13 @@ pub fn get_builtin_op_assignment_fn(op: &Token, x: &Dynamic, y: &Dynamic) -> Opt
if type1 == TypeId::of::<crate::Array>() {
#[allow(clippy::wildcard_imports)]
use crate::packages::array_basic::array_functions::*;
use crate::Array;

return match op {
PlusAssign => Some((
|_ctx, args| {
{
let x = args[1].take();
let array = &mut *args[0].write_lock::<Array>().unwrap();
let array = &mut *args[0].as_array_ref_mut().unwrap();
push(array, x);
}

Expand Down Expand Up @@ -1050,7 +1045,7 @@ pub fn get_builtin_op_assignment_fn(op: &Token, x: &Dynamic, y: &Dynamic) -> Opt
PlusAssign => Some((
|_ctx, args| {
let x = args[1].as_int().unwrap();
let blob = &mut *args[0].write_lock::<Blob>().unwrap();
let blob = &mut *args[0].as_blob_ref_mut().unwrap();

#[cfg(not(feature = "unchecked"))]
_ctx.unwrap()
Expand All @@ -1076,7 +1071,7 @@ pub fn get_builtin_op_assignment_fn(op: &Token, x: &Dynamic, y: &Dynamic) -> Opt
PlusAssign => Some((
|_ctx, args| {
let x = args[1].as_char().unwrap();
let blob = &mut *args[0].write_lock::<Blob>().unwrap();
let blob = &mut *args[0].as_blob_ref_mut().unwrap();

#[cfg(not(feature = "unchecked"))]
_ctx.unwrap()
Expand All @@ -1102,8 +1097,8 @@ pub fn get_builtin_op_assignment_fn(op: &Token, x: &Dynamic, y: &Dynamic) -> Opt
PlusAssign => Some((
|_ctx, args| {
let (first, second) = args.split_first_mut().unwrap();
let blob = &mut *first.write_lock::<Blob>().unwrap();
let s = &*second[0].read_lock::<ImmutableString>().unwrap();
let blob = &mut *first.as_blob_ref_mut().unwrap();
let s = &*second[0].as_immutable_string_ref().unwrap();

if s.is_empty() {
return Ok(Dynamic::UNIT);
Expand Down
4 changes: 2 additions & 2 deletions src/packages/array_basic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1638,8 +1638,8 @@ pub mod array_functions {
}
if type_id == TypeId::of::<ImmutableString>() {
array.sort_by(|a, b| {
let a = &*a.read_lock::<ImmutableString>().unwrap();
let b = &*b.read_lock::<ImmutableString>().unwrap();
let a = &*a.as_immutable_string_ref().unwrap();
let b = &*b.as_immutable_string_ref().unwrap();
a.cmp(b)
});
return Ok(());
Expand Down
6 changes: 3 additions & 3 deletions src/serde/de.rs
Original file line number Diff line number Diff line change
Expand Up @@ -470,9 +470,9 @@ impl<'de> Deserializer<'de> for DynamicDeserializer<'de> {
_variants: &'static [&'static str],
visitor: V,
) -> RhaiResultOf<V::Value> {
match self.0.read_lock::<ImmutableString>() {
Some(s) => visitor.visit_enum(s.into_deserializer()),
None => {
match self.0.as_immutable_string_ref() {
Ok(s) => visitor.visit_enum(s.into_deserializer()),
Err(_) => {
#[cfg(not(feature = "no_object"))]
return self.0.downcast_ref::<crate::Map>().map_or_else(
|| self.type_error(),
Expand Down
2 changes: 1 addition & 1 deletion src/serde/ser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ impl DynamicSerializer {
/// assert!(value.is::<Map>());
///
/// let map = value.cast::<Map>();
/// let point = map["d"].read_lock::<Map>().unwrap();
/// let point = map["d"].as_map().unwrap();
/// assert_eq!(*point["x"].read_lock::<f64>().unwrap(), 123.456);

Check failure on line 77 in src/serde/ser.rs

View workflow job for this annotation

GitHub Actions / Build (ubuntu-latest, --features testing-environ,no_function,serde,metadata,internals,debugging, ...

no method named `as_map` found for struct `Dynamic` in the current scope

Check failure on line 77 in src/serde/ser.rs

View workflow job for this annotation

GitHub Actions / Build (ubuntu-latest, --features testing-environ,no_module,serde,metadata,internals,debugging, st...

no method named `as_map` found for struct `Dynamic` in the current scope

Check failure on line 77 in src/serde/ser.rs

View workflow job for this annotation

GitHub Actions / Build (ubuntu-latest, --features testing-environ,no_optimize,serde,metadata,internals,debugging, ...

no method named `as_map` found for struct `Dynamic` in the current scope

Check failure on line 77 in src/serde/ser.rs

View workflow job for this annotation

GitHub Actions / Build (ubuntu-latest, --features testing-environ,no_closure,serde,metadata,internals,debugging, s...

no method named `as_map` found for struct `Dynamic` in the current scope

Check failure on line 77 in src/serde/ser.rs

View workflow job for this annotation

GitHub Actions / Build (ubuntu-latest, --features testing-environ,only_i64,serde,metadata,internals,debugging, sta...

no method named `as_map` found for struct `Dynamic` in the current scope

Check failure on line 77 in src/serde/ser.rs

View workflow job for this annotation

GitHub Actions / Build (ubuntu-latest, --features testing-environ,no_time,serde,metadata,internals,debugging, stab...

no method named `as_map` found for struct `Dynamic` in the current scope

Check failure on line 77 in src/serde/ser.rs

View workflow job for this annotation

GitHub Actions / Build (ubuntu-latest, --features testing-environ,metadata, stable, false)

no method named `as_map` found for struct `Dynamic` in the current scope

Check failure on line 77 in src/serde/ser.rs

View workflow job for this annotation

GitHub Actions / Build (ubuntu-latest, --features testing-environ,no_custom_syntax,serde,metadata,internals,debugg...

no method named `as_map` found for struct `Dynamic` in the current scope

Check failure on line 77 in src/serde/ser.rs

View workflow job for this annotation

GitHub Actions / Build (ubuntu-latest, --features testing-environ,no_position,serde,metadata,internals,debugging, ...

no method named `as_map` found for struct `Dynamic` in the current scope

Check failure on line 77 in src/serde/ser.rs

View workflow job for this annotation

GitHub Actions / Build (ubuntu-latest, --features testing-environ,sync,serde,metadata,internals,debugging, stable,...

no method named `as_map` found for struct `Dynamic` in the current scope

Check failure on line 77 in src/serde/ser.rs

View workflow job for this annotation

GitHub Actions / Build (ubuntu-latest, --features testing-environ,unchecked,serde,metadata,internals,debugging, st...

no method named `as_map` found for struct `Dynamic` in the current scope

Check failure on line 77 in src/serde/ser.rs

View workflow job for this annotation

GitHub Actions / Build (ubuntu-latest, --features testing-environ,decimal,serde,metadata,internals,debugging, stab...

no method named `as_map` found for struct `Dynamic` in the current scope
/// assert_eq!(*point["y"].read_lock::<f64>().unwrap(), 999.0);
/// # }
Expand Down
Loading

0 comments on commit e343641

Please sign in to comment.