Add take function.

This commit is contained in:
Stephen Chung 2023-05-13 09:31:57 +08:00
parent d84008dda0
commit b1fbfcbc07
3 changed files with 67 additions and 0 deletions

View File

@ -8,6 +8,7 @@ Enhancements
------------ ------------
* Expressions involving `this` should now run slightly faster due to a dedicated `AST` node `ThisPtr`. * Expressions involving `this` should now run slightly faster due to a dedicated `AST` node `ThisPtr`.
* A `take` function is added to the standard library to take ownership of any data (replacing with `()`) in order to avoid cloning.
Version 1.14.0 Version 1.14.0

View File

@ -26,6 +26,30 @@ def_package! {
#[export_module] #[export_module]
mod core_functions { mod core_functions {
/// Take ownership of the data in a `Dynamic` value and return it.
/// The data is _NOT_ cloned.
///
/// The original value is replaced with `()`.
///
/// # Example
///
/// ```rhai
/// let x = 42;
///
/// print(take(x)); // prints 42
///
/// print(x); // prints ()
/// ```
#[rhai_fn(return_raw)]
pub fn take(value: &mut Dynamic) -> RhaiResultOf<Dynamic> {
if value.is_read_only() {
return Err(
ERR::ErrorNonPureMethodCallOnConstant("take".to_string(), Position::NONE).into(),
);
}
Ok(std::mem::take(value))
}
/// Return the _tag_ of a `Dynamic` value. /// Return the _tag_ of a `Dynamic` value.
/// ///
/// # Example /// # Example

View File

@ -64,6 +64,48 @@ fn test_internal_fn() -> Result<(), Box<EvalAltResult>> {
Ok(()) Ok(())
} }
#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Default)]
struct TestStruct(INT);
impl Clone for TestStruct {
fn clone(&self) -> Self {
Self(self.0 + 1)
}
}
#[test]
fn test_internal_fn_take() -> Result<(), Box<EvalAltResult>> {
let mut engine = Engine::new();
engine
.register_type_with_name::<TestStruct>("TestStruct")
.register_fn("new_ts", |x: INT| TestStruct(x));
assert_eq!(
engine.eval::<TestStruct>(
"
let x = new_ts(0);
for n in 0..41 { x = x }
x
",
)?,
TestStruct(42)
);
assert_eq!(
engine.eval::<TestStruct>(
"
let x = new_ts(0);
for n in 0..41 { x = take(x) }
take(x)
",
)?,
TestStruct(0)
);
Ok(())
}
#[test] #[test]
fn test_internal_fn_big() -> Result<(), Box<EvalAltResult>> { fn test_internal_fn_big() -> Result<(), Box<EvalAltResult>> {
let engine = Engine::new(); let engine = Engine::new();