Add get/set methods to arrays, blobs, maps and strings.
This commit is contained in:
parent
573bfe46dd
commit
5232bbbff8
@ -22,6 +22,7 @@ Enhancements
|
||||
* Formatting of return types in functions metadata info is improved.
|
||||
* Use `SmartString` for `Scope` variable names and remove `unsafe` lifetime casting.
|
||||
* Functions in the standard library now have doc-comments (which can be obtained via `Engine::gen_fn_metadata_to_json`).
|
||||
* `get` and `set` methods are added to arrays, BLOB's, object maps and strings.
|
||||
|
||||
|
||||
Version 1.4.0
|
||||
|
@ -31,6 +31,70 @@ pub mod array_functions {
|
||||
pub fn len(array: &mut Array) -> INT {
|
||||
array.len() as INT
|
||||
}
|
||||
/// Get a copy of the element at the `index` position in the array.
|
||||
///
|
||||
/// * If `index` < 0, position counts from the end of the array (`-1` is the last element).
|
||||
/// * If `index` < -length of array, `()` is returned.
|
||||
/// * If `index` ≥ length of array, `()` is returned.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```rhai
|
||||
/// let x = [1, 2, 3];
|
||||
///
|
||||
/// print(x.get(0)); // prints 1
|
||||
///
|
||||
/// print(x.get(-1)); // prints 3
|
||||
///
|
||||
/// print(x.get(99)); // prints empty (for '()')
|
||||
/// ```
|
||||
pub fn get(array: &mut Array, index: INT) -> Dynamic {
|
||||
if array.is_empty() {
|
||||
return Dynamic::UNIT;
|
||||
}
|
||||
|
||||
let (index, _) = calc_offset_len(array.len(), index, 0);
|
||||
|
||||
if index >= array.len() {
|
||||
Dynamic::UNIT
|
||||
} else {
|
||||
array[index].clone()
|
||||
}
|
||||
}
|
||||
/// Set the element at the `index` position in the array to a new `value`.
|
||||
///
|
||||
/// * If `index` < 0, position counts from the end of the array (`-1` is the last element).
|
||||
/// * If `index` < -length of array, the array is not modified.
|
||||
/// * If `index` ≥ length of array, the array is not modified.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```rhai
|
||||
/// let x = [1, 2, 3];
|
||||
///
|
||||
/// x.set(0, 42);
|
||||
///
|
||||
/// print(x); // prints "[42, 2, 3]"
|
||||
///
|
||||
/// x.set(-3, 0);
|
||||
///
|
||||
/// print(x); // prints "[0, 2, 3]"
|
||||
///
|
||||
/// x.set(99, 123);
|
||||
///
|
||||
/// print(x); // prints "[0, 2, 3]"
|
||||
/// ```
|
||||
pub fn set(array: &mut Array, index: INT, value: Dynamic) {
|
||||
if array.is_empty() {
|
||||
return;
|
||||
}
|
||||
|
||||
let (index, _) = calc_offset_len(array.len(), index, 0);
|
||||
|
||||
if index < array.len() {
|
||||
array[index] = value;
|
||||
}
|
||||
}
|
||||
/// Add a new element, which is not another array, to the end of the array.
|
||||
///
|
||||
/// If `item` is `Array`, then `append` is more specific and will be called instead.
|
||||
|
@ -100,6 +100,75 @@ pub mod blob_functions {
|
||||
pub fn len(blob: &mut Blob) -> INT {
|
||||
blob.len() as INT
|
||||
}
|
||||
|
||||
/// Get the byte value at the `index` position in the BLOB.
|
||||
///
|
||||
/// * If `index` < 0, position counts from the end of the BLOB (`-1` is the last element).
|
||||
/// * If `index` < -length of BLOB, zero is returned.
|
||||
/// * If `index` ≥ length of BLOB, zero is returned.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```rhai
|
||||
/// let b = blob();
|
||||
///
|
||||
/// b += 1; b += 2; b += 3; b += 4; b += 5;
|
||||
///
|
||||
/// print(b.get(0)); // prints 1
|
||||
///
|
||||
/// print(b.get(-1)); // prints 5
|
||||
///
|
||||
/// print(b.get(99)); // prints 0
|
||||
/// ```
|
||||
pub fn get(blob: &mut Blob, index: INT) -> INT {
|
||||
if blob.is_empty() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
let (index, _) = calc_offset_len(blob.len(), index, 0);
|
||||
|
||||
if index >= blob.len() {
|
||||
0
|
||||
} else {
|
||||
blob[index] as INT
|
||||
}
|
||||
}
|
||||
/// Set the particular `index` position in the BLOB to a new byte `value`.
|
||||
///
|
||||
/// * If `index` < 0, position counts from the end of the BLOB (`-1` is the last byte).
|
||||
/// * If `index` < -length of BLOB, the BLOB is not modified.
|
||||
/// * If `index` ≥ length of BLOB, the BLOB is not modified.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```rhai
|
||||
/// let b = blob();
|
||||
///
|
||||
/// b += 1; b += 2; b += 3; b += 4; b += 5;
|
||||
///
|
||||
/// b.set(0, 0x42);
|
||||
///
|
||||
/// print(b); // prints "[4202030405]"
|
||||
///
|
||||
/// b.set(-3, 0);
|
||||
///
|
||||
/// print(b); // prints "[4202000405]"
|
||||
///
|
||||
/// b.set(99, 123);
|
||||
///
|
||||
/// print(b); // prints "[4202000405]"
|
||||
/// ```
|
||||
pub fn set(blob: &mut Blob, index: INT, value: INT) {
|
||||
if blob.is_empty() {
|
||||
return;
|
||||
}
|
||||
|
||||
let (index, _) = calc_offset_len(blob.len(), index, 0);
|
||||
|
||||
if index < blob.len() {
|
||||
blob[index] = (value & 0x000000ff) as u8;
|
||||
}
|
||||
}
|
||||
/// Add a new byte `value` to the end of the BLOB.
|
||||
///
|
||||
/// Only the lower 8 bits of the `value` are used; all other bits are ignored.
|
||||
@ -114,8 +183,7 @@ pub mod blob_functions {
|
||||
/// print(b); // prints "[42]"
|
||||
/// ```
|
||||
pub fn push(blob: &mut Blob, value: INT) {
|
||||
let value = (value & 0x000000ff) as u8;
|
||||
blob.push(value);
|
||||
blob.push((value & 0x000000ff) as u8);
|
||||
}
|
||||
/// Add another BLOB to the end of the BLOB.
|
||||
///
|
||||
|
@ -25,6 +25,51 @@ mod map_functions {
|
||||
pub fn len(map: &mut Map) -> INT {
|
||||
map.len() as INT
|
||||
}
|
||||
|
||||
/// Get the value of the `property` in the object map and return a copy.
|
||||
///
|
||||
/// If `property` does not exist in the object map, `()` is returned.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```rhai
|
||||
/// let m = #{a: 1, b: 2, c: 3};
|
||||
///
|
||||
/// print(m.get("b")); // prints 2
|
||||
///
|
||||
/// print(m.get("x")); // prints empty (for '()')
|
||||
/// ```
|
||||
pub fn get(map: &mut Map, property: &str) -> Dynamic {
|
||||
if map.is_empty() {
|
||||
return Dynamic::UNIT;
|
||||
}
|
||||
|
||||
map.get(property).cloned().unwrap_or(Dynamic::UNIT)
|
||||
}
|
||||
/// Set the value of the `property` in the object map to a new `value`.
|
||||
///
|
||||
/// If `property` does not exist in the object map, it is added.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```rhai
|
||||
/// let m = #{a: 1, b: 2, c: 3};
|
||||
///
|
||||
/// m.set("b", 42)'
|
||||
///
|
||||
/// print(m); // prints "#{a: 1, b: 42, c: 3}"
|
||||
///
|
||||
/// x.set("x", 0);
|
||||
///
|
||||
/// print(m); // prints "#{a: 1, b: 42, c: 3, x: 0}"
|
||||
/// ```
|
||||
pub fn set(map: &mut Map, property: &str, value: Dynamic) {
|
||||
if let Some(value_ref) = map.get_mut(property) {
|
||||
*value_ref = value;
|
||||
} else {
|
||||
map.insert(property.into(), value);
|
||||
}
|
||||
}
|
||||
/// Clear the object map.
|
||||
pub fn clear(map: &mut Map) {
|
||||
if !map.is_empty() {
|
||||
@ -46,9 +91,9 @@ mod map_functions {
|
||||
///
|
||||
/// print(m); // prints "#{a:1, c:3}"
|
||||
/// ```
|
||||
pub fn remove(map: &mut Map, name: ImmutableString) -> Dynamic {
|
||||
pub fn remove(map: &mut Map, property: &str) -> Dynamic {
|
||||
if !map.is_empty() {
|
||||
map.remove(name.as_str()).unwrap_or_else(|| Dynamic::UNIT)
|
||||
map.remove(property).unwrap_or_else(|| Dynamic::UNIT)
|
||||
} else {
|
||||
Dynamic::UNIT
|
||||
}
|
||||
|
@ -551,6 +551,85 @@ mod string_functions {
|
||||
}
|
||||
}
|
||||
|
||||
/// Get the character at the `index` position in the string.
|
||||
///
|
||||
/// * If `index` < 0, position counts from the end of the string (`-1` is the last character).
|
||||
/// * If `index` < -length of string, zero is returned.
|
||||
/// * If `index` ≥ length of string, zero is returned.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```rhai
|
||||
/// let text = "hello, world!";
|
||||
///
|
||||
/// print(text.get(0)); // prints 'h'
|
||||
///
|
||||
/// print(text.get(-1)); // prints '!'
|
||||
///
|
||||
/// print(text.get(99)); // prints empty (for '()')'
|
||||
/// ```
|
||||
pub fn get(string: &str, index: INT) -> Dynamic {
|
||||
if index >= 0 {
|
||||
string
|
||||
.chars()
|
||||
.nth(index as usize)
|
||||
.map_or_else(|| Dynamic::UNIT, Into::into)
|
||||
} else if let Some(abs_index) = index.checked_abs() {
|
||||
// Count from end if negative
|
||||
string
|
||||
.chars()
|
||||
.rev()
|
||||
.nth((abs_index as usize) - 1)
|
||||
.map_or_else(|| Dynamic::UNIT, Into::into)
|
||||
} else {
|
||||
Dynamic::UNIT
|
||||
}
|
||||
}
|
||||
/// Set the `index` position in the string to a new `character`.
|
||||
///
|
||||
/// * If `index` < 0, position counts from the end of the string (`-1` is the last character).
|
||||
/// * If `index` < -length of string, the string is not modified.
|
||||
/// * If `index` ≥ length of string, the string is not modified.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```rhai
|
||||
/// let text = "hello, world!";
|
||||
///
|
||||
/// text.set(3, 'x');
|
||||
///
|
||||
/// print(text); // prints "helxo, world!"
|
||||
///
|
||||
/// text.set(-3, 'x');
|
||||
///
|
||||
/// print(text); // prints "hello, worxd!"
|
||||
///
|
||||
/// text.set(99, 'x');
|
||||
///
|
||||
/// print(text); // prints "hello, worxd!"
|
||||
/// ```
|
||||
pub fn set(string: &mut ImmutableString, index: INT, character: char) {
|
||||
if index >= 0 {
|
||||
let index = index as usize;
|
||||
*string = string
|
||||
.chars()
|
||||
.enumerate()
|
||||
.map(|(i, ch)| if i == index { character } else { ch })
|
||||
.collect();
|
||||
} else if let Some(abs_index) = index.checked_abs() {
|
||||
let string_len = string.chars().count();
|
||||
|
||||
if abs_index as usize <= string_len {
|
||||
let index = string_len - (abs_index as usize);
|
||||
*string = string
|
||||
.chars()
|
||||
.enumerate()
|
||||
.map(|(i, ch)| if i == index { character } else { ch })
|
||||
.collect();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Copy an exclusive range of characters from the string and return it as a new string.
|
||||
///
|
||||
/// # Example
|
||||
|
Loading…
Reference in New Issue
Block a user