Skip to content

Commit

Permalink
Merge pull request #904 from schungx/master
Browse files Browse the repository at this point in the history
Add as_XXX_ref and as_XXX_ref_mut to Dynamic.
  • Loading branch information
schungx authored Jul 27, 2024
2 parents 03730d8 + a6e1ba1 commit 7baff78
Show file tree
Hide file tree
Showing 15 changed files with 280 additions and 94 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
6 changes: 1 addition & 5 deletions codegen/src/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,8 @@ use syn::{
spanned::Spanned,
};

#[cfg(no_std)]
use alloc::format;
#[cfg(not(no_std))]
use std::format;

use std::borrow::Cow;
use std::format;

use crate::attrs::{ExportInfo, ExportScope, ExportedParams};

Expand Down
6 changes: 1 addition & 5 deletions codegen/src/module.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@
use quote::{quote, ToTokens};
use syn::{parse::Parse, parse::ParseStream};

#[cfg(no_std)]
use core::mem;
#[cfg(not(no_std))]
use std::mem;

use std::borrow::Cow;
use std::mem;

use crate::attrs::{AttrItem, ExportInfo, ExportScope, ExportedParams};
use crate::function::ExportedFn;
Expand Down
11 changes: 11 additions & 0 deletions codegen/ui_tests/export_fn_cfg.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,17 @@ error: `cfg` attributes are not allowed for `export_fn`
10 | #[cfg(not(feature = "foo"))]
| ^

warning: unexpected `cfg` condition value: `foo`
--> ui_tests/export_fn_cfg.rs:10:11
|
10 | #[cfg(not(feature = "foo"))]
| ^^^^^^^^^^^^^^^
|
= note: expected values for `feature` are: `default` and `metadata`
= help: consider adding `foo` as a feature in `Cargo.toml`
= note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg/cargo-specifics.html> for more information about checking conditional configuration
= note: `#[warn(unexpected_cfgs)]` on by default

error[E0425]: cannot find function `test_fn` in this scope
--> ui_tests/export_fn_cfg.rs:18:8
|
Expand Down
11 changes: 11 additions & 0 deletions codegen/ui_tests/rhai_mod_inner_cfg_false.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,14 @@ note: found an item that was configured out
12 | pub mod test_mod {
| ^^^^^^^^
= note: the item is gated behind the `unset_feature` feature

warning: unexpected `cfg` condition value: `unset_feature`
--> ui_tests/rhai_mod_inner_cfg_false.rs:11:11
|
11 | #[cfg(feature = "unset_feature")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: expected values for `feature` are: `default` and `metadata`
= help: consider adding `unset_feature` as a feature in `Cargo.toml`
= note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg/cargo-specifics.html> for more information about checking conditional configuration
= note: `#[warn(unexpected_cfgs)]` on by default
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_ref().expect("c should exist");
/// assert_eq!(c["x"].as_bool().expect("x should be bool"), false);
/// 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_ref().unwrap();
/// assert_eq!(*point["x"].read_lock::<f64>().unwrap(), 123.456);
/// assert_eq!(*point["y"].read_lock::<f64>().unwrap(), 999.0);
/// # }
Expand Down
Loading

0 comments on commit 7baff78

Please sign in to comment.