Reimplement pad for string.
This commit is contained in:
parent
ea814779bf
commit
25f820f5bf
@ -30,36 +30,36 @@ Built-in Functions
|
||||
|
||||
The following methods (mostly defined in the [`BasicArrayPackage`][packages] but excluded if using a [raw `Engine`]) operate on arrays:
|
||||
|
||||
| Function | Parameter(s) | Description |
|
||||
| ------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `push` | element to insert | inserts an element at the end |
|
||||
| `append` | array to append | concatenates the second array to the end of the first |
|
||||
| `+=` operator | 1) array<br/>2) element to insert (not another array) | inserts an element at the end |
|
||||
| `+=` operator | 1) array<br/>2) array to append | concatenates the second array to the end of the first |
|
||||
| `+` operator | 1) first array<br/>2) second array | concatenates the first array with the second |
|
||||
| `insert` | 1) element to insert<br/>2) position, beginning if < 0, end if > length | inserts an element at a certain index |
|
||||
| `pop` | _none_ | removes the last element and returns it ([`()`] if empty) |
|
||||
| `shift` | _none_ | removes the first element and returns it ([`()`] if empty) |
|
||||
| `extract` | 1) start position, beginning if < 0, end if > length,<br/>2) _(optional)_ number of items to extract, none if < 0 | extracts a portion of the array into a new array |
|
||||
| `remove` | index | removes an element at a particular index and returns it ([`()`] if the index is not valid) |
|
||||
| `reverse` | _none_ | reverses the array |
|
||||
| `len` method and property | _none_ | returns the number of elements |
|
||||
| `pad` | 1) target length<br/>2) element to pad | pads the array with an element to at least a specified length |
|
||||
| `clear` | _none_ | empties the array |
|
||||
| `truncate` | target length | cuts off the array at exactly a specified length (discarding all subsequent elements) |
|
||||
| `chop` | target length | cuts off the head of the array, leaving the tail at exactly a specified length |
|
||||
| `drain` | 1) [function pointer] to predicate (usually a [closure]),<br/>2) _(optional)_ [function pointer] to function (usually a [closure]) that provides the initial value | removes all items (returning them) that return `true` when called with the predicate function:<br/>1st parameter: array item,<br/>2nd parameter: _(optional)_ offset index |
|
||||
| `drain` | 1) start position, beginning if < 0, end if > length,<br/>2) number of items to remove, none if < 0 | removes a portion of the array, returning the removed items (not in original order) |
|
||||
| `retain` | 1) [function pointer] to predicate (usually a [closure]),<br/>2) _(optional)_ [function pointer] to function (usually a [closure]) that provides the initial value | removes all items (returning them) that do not return `true` when called with the predicate function:<br/>1st parameter: array item,<br/>2nd parameter: _(optional)_ offset index |
|
||||
| `retain` | 1) start position, beginning if < 0, end if > length,<br/>2) number of items to retain, none if < 0 | retains a portion of the array, removes all other items and returning them (not in original order) |
|
||||
| `splice` | 1) start position, beginning if < 0, end if > length,<br/>2) number of items to remove, none if < 0,<br/>3) array to insert | replaces a portion of the array with another (not necessarily of the same length as the replaced portion) |
|
||||
| `filter` | [function pointer] to predicate (usually a [closure]) | constructs a new array with all items that return `true` when called with the predicate function:<br/>1st parameter: array item,<br/>2nd parameter: _(optional)_ offset index |
|
||||
| `map` | [function pointer] to conversion function (usually a [closure]) | constructs a new array with all items mapped to the result of applying the conversion function:<br/>1st parameter: array item,<br/>2nd parameter: _(optional)_ offset index |
|
||||
| `reduce` | 1) [function pointer] to accumulator function (usually a [closure]),<br/>2) _(optional)_ [function pointer] to function (usually a [closure]) that provides the initial value | reduces the array into a single value via the accumulator function:<br/>1st parameter: accumulated value ([`()`] initially),<br/>2nd parameter: array item,<br/>3rd parameter: _(optional)_ offset index |
|
||||
| `reduce_rev` | 1) [function pointer] to accumulator function (usually a [closure]),<br/>2) _(optional)_ [function pointer] to function (usually a [closure]) that provides the initial value | reduces the array (in reverse order) into a single value via the accumulator function:<br/>1st parameter: accumulated value ([`()`] initially),<br/>2nd parameter: array item,<br/>3rd parameter: _(optional)_ offset index |
|
||||
| `some` | [function pointer] to predicate (usually a [closure]) | returns `true` if any item returns `true` when called with the predicate function:<br/>1st parameter: array item,<br/>2nd parameter: _(optional)_ offset index |
|
||||
| `all` | [function pointer] to predicate (usually a [closure]) | returns `true` if all items return `true` when called with the predicate function:<br/>1st parameter: array item,<br/>2nd parameter: _(optional)_ offset index |
|
||||
| `sort` | [function pointer] to a comparison function (usually a [closure]) | sorts the array with a comparison function:<br/>1st parameter: first item,<br/>2nd parameter: second item,<br/>return value: `INT` < 0 if first < second, > 0 if first > second, 0 if first == second |
|
||||
| Function | Parameter(s) | Description |
|
||||
| ------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `push` | element to insert | inserts an element at the end |
|
||||
| `append` | array to append | concatenates the second array to the end of the first |
|
||||
| `+=` operator | 1) array<br/>2) element to insert (not another array) | inserts an element at the end |
|
||||
| `+=` operator | 1) array<br/>2) array to append | concatenates the second array to the end of the first |
|
||||
| `+` operator | 1) first array<br/>2) second array | concatenates the first array with the second |
|
||||
| `insert` | 1) element to insert<br/>2) position, beginning if < 0, end if > length | inserts an element at a certain index |
|
||||
| `pop` | _none_ | removes the last element and returns it ([`()`] if empty) |
|
||||
| `shift` | _none_ | removes the first element and returns it ([`()`] if empty) |
|
||||
| `extract` | 1) start position, beginning if < 0, end if > length<br/>2) _(optional)_ number of items to extract, none if < 0 | extracts a portion of the array into a new array |
|
||||
| `remove` | index | removes an element at a particular index and returns it ([`()`] if the index is not valid) |
|
||||
| `reverse` | _none_ | reverses the array |
|
||||
| `len` method and property | _none_ | returns the number of elements |
|
||||
| `pad` | 1) target length<br/>2) element to pad | pads the array with an element to at least a specified length |
|
||||
| `clear` | _none_ | empties the array |
|
||||
| `truncate` | target length | cuts off the array at exactly a specified length (discarding all subsequent elements) |
|
||||
| `chop` | target length | cuts off the head of the array, leaving the tail at exactly a specified length |
|
||||
| `drain` | 1) [function pointer] to predicate (usually a [closure])<br/>2) _(optional)_ [function pointer] to function (usually a [closure]) that provides the initial value | removes all items (returning them) that return `true` when called with the predicate function:<br/>1st parameter: array item<br/>2nd parameter: _(optional)_ offset index |
|
||||
| `drain` | 1) start position, beginning if < 0, end if > length<br/>2) number of items to remove, none if < 0 | removes a portion of the array, returning the removed items (not in original order) |
|
||||
| `retain` | 1) [function pointer] to predicate (usually a [closure])<br/>2) _(optional)_ [function pointer] to function (usually a [closure]) that provides the initial value | removes all items (returning them) that do not return `true` when called with the predicate function:<br/>1st parameter: array item<br/>2nd parameter: _(optional)_ offset index |
|
||||
| `retain` | 1) start position, beginning if < 0, end if > length<br/>2) number of items to retain, none if < 0 | retains a portion of the array, removes all other items and returning them (not in original order) |
|
||||
| `splice` | 1) start position, beginning if < 0, end if > length<br/>2) number of items to remove, none if < 0<br/>3) array to insert | replaces a portion of the array with another (not necessarily of the same length as the replaced portion) |
|
||||
| `filter` | [function pointer] to predicate (usually a [closure]) | constructs a new array with all items that return `true` when called with the predicate function:<br/>1st parameter: array item<br/>2nd parameter: _(optional)_ offset index |
|
||||
| `map` | [function pointer] to conversion function (usually a [closure]) | constructs a new array with all items mapped to the result of applying the conversion function:<br/>1st parameter: array item<br/>2nd parameter: _(optional)_ offset index |
|
||||
| `reduce` | 1) [function pointer] to accumulator function (usually a [closure])<br/>2) _(optional)_ [function pointer] to function (usually a [closure]) that provides the initial value | reduces the array into a single value via the accumulator function:<br/>1st parameter: accumulated value ([`()`] initially)<br/>2nd parameter: array item<br/>3rd parameter: _(optional)_ offset index |
|
||||
| `reduce_rev` | 1) [function pointer] to accumulator function (usually a [closure])<br/>2) _(optional)_ [function pointer] to function (usually a [closure]) that provides the initial value | reduces the array (in reverse order) into a single value via the accumulator function:<br/>1st parameter: accumulated value ([`()`] initially)<br/>2nd parameter: array item<br/>3rd parameter: _(optional)_ offset index |
|
||||
| `some` | [function pointer] to predicate (usually a [closure]) | returns `true` if any item returns `true` when called with the predicate function:<br/>1st parameter: array item<br/>2nd parameter: _(optional)_ offset index |
|
||||
| `all` | [function pointer] to predicate (usually a [closure]) | returns `true` if all items return `true` when called with the predicate function:<br/>1st parameter: array item<br/>2nd parameter: _(optional)_ offset index |
|
||||
| `sort` | [function pointer] to a comparison function (usually a [closure]) | sorts the array with a comparison function:<br/>1st parameter: first item<br/>2nd parameter: second item<br/>return value: `INT` < 0 if first < second, > 0 if first > second, 0 if first == second |
|
||||
|
||||
|
||||
Use Custom Types With Arrays
|
||||
|
@ -226,7 +226,7 @@ engine.register_raw_fn("super_call",
|
||||
`FnPtr::call_dynamic` takes a parameter of type `NativeCallContext` which holds the _native call context_
|
||||
of the particular call to a registered Rust function.
|
||||
|
||||
This type is normally provided by the [`Engine`] (e.g. when using `Engine::register_fn_raw`(../rust/register-raw.md)).
|
||||
This type is normally provided by the [`Engine`] (e.g. when using [`Engine::register_fn_raw`](../rust/register-raw.md)).
|
||||
However, it may also be manually constructed from a tuple:
|
||||
|
||||
```rust
|
||||
|
@ -9,7 +9,7 @@ using a [raw `Engine`]) operate on [strings]:
|
||||
| Function | Parameter(s) | Description |
|
||||
| ------------------------- | ------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- |
|
||||
| `len` method and property | _none_ | returns the number of characters (not number of bytes) in the string |
|
||||
| `pad` | 1) character to pad<br/>2) target length | pads the string with an character to at least a specified length |
|
||||
| `pad` | 1) target length<br/>2) character/string to pad | pads the string with a character or a string to at least a specified length |
|
||||
| `+=` operator, `append` | character/string to append | Adds a character or a string to the end of another string |
|
||||
| `clear` | _none_ | empties the string |
|
||||
| `truncate` | target length | cuts off the string at exactly a specified number of characters |
|
||||
|
@ -102,9 +102,10 @@ as a parameter to the function, thereby implementing a _callback_:
|
||||
use rhai::{Dynamic, FnPtr, NativeCallContext, EvalAltResult};
|
||||
use rhai::plugin::*; // a "prelude" import for macros
|
||||
|
||||
#[export_fn(return_raw)]
|
||||
#[export_fn]
|
||||
#[rhai_fn(return_raw)]
|
||||
pub fn greet(context: NativeCallContext, callback: FnPtr)
|
||||
-> Result<Dynamic, Box<EvalAltResult>>
|
||||
-> Result<Dynamic, Box<EvalAltResult>>
|
||||
{
|
||||
// Call the callback closure with the current context
|
||||
// to obtain the name to greet!
|
||||
@ -116,15 +117,16 @@ pub fn greet(context: NativeCallContext, callback: FnPtr)
|
||||
The native call context is also useful in another scenario: protecting a function from malicious scripts.
|
||||
|
||||
```rust
|
||||
use rhai::{Dynamic, INT, Array, NativeCallContext, EvalAltResult, Position};
|
||||
use rhai::{Dynamic, Array, NativeCallContext, EvalAltResult, Position};
|
||||
use rhai::plugin::*; // a "prelude" import for macros
|
||||
|
||||
// This function builds an array of arbitrary size, but is protected
|
||||
// against attacks by first checking with the allowed limit set
|
||||
// into the 'Engine'.
|
||||
#[export_fn(return_raw)]
|
||||
pub fn grow(context: NativeCallContext, size: INT)
|
||||
-> Result<Dynamic, Box<EvalAltResult>>
|
||||
#[export_fn]
|
||||
#[rhai_fn(return_raw)]
|
||||
pub fn grow(context: NativeCallContext, size: i64)
|
||||
-> Result<Dynamic, Box<EvalAltResult>>
|
||||
{
|
||||
// Make sure the function does not generate a
|
||||
// data structure larger than the allowed limit
|
||||
|
@ -363,7 +363,7 @@ use rhai::plugin::*; // a "prelude" import for macros
|
||||
mod my_module {
|
||||
#[rhai_fn(return_raw)]
|
||||
pub fn greet(context: NativeCallContext, callback: FnPtr)
|
||||
-> Result<Dynamic, Box<EvalAltResult>>
|
||||
-> Result<Dynamic, Box<EvalAltResult>>
|
||||
{
|
||||
// Call the callback closure with the current context
|
||||
// to obtain the name to greet!
|
||||
@ -376,7 +376,7 @@ mod my_module {
|
||||
The native call context is also useful in another scenario: protecting a function from malicious scripts.
|
||||
|
||||
```rust
|
||||
use rhai::{Dynamic, INT, Array, NativeCallContext, EvalAltResult, Position};
|
||||
use rhai::{Dynamic, Array, NativeCallContext, EvalAltResult, Position};
|
||||
use rhai::plugin::*; // a "prelude" import for macros
|
||||
|
||||
#[export_module]
|
||||
@ -385,8 +385,8 @@ mod my_module {
|
||||
// against attacks by first checking with the allowed limit set
|
||||
// into the 'Engine'.
|
||||
#[rhai_fn(return_raw)]
|
||||
pub fn grow(context: NativeCallContext, size: INT)
|
||||
-> Result<Dynamic, Box<EvalAltResult>>
|
||||
pub fn grow(context: NativeCallContext, size: i64)
|
||||
-> Result<Dynamic, Box<EvalAltResult>>
|
||||
{
|
||||
// Make sure the function does not generate a
|
||||
// data structure larger than the allowed limit
|
||||
|
@ -60,7 +60,8 @@ Function Signature
|
||||
|
||||
The function signature passed to `Engine::register_raw_fn` takes the following form:
|
||||
|
||||
> `Fn(context: NativeCallContext, args: &mut [&mut Dynamic]) -> Result<T, Box<EvalAltResult>> + 'static`
|
||||
> `Fn(context: NativeCallContext, args: &mut [&mut Dynamic])`
|
||||
> `-> Result<T, Box<EvalAltResult>> + 'static`
|
||||
|
||||
where:
|
||||
|
||||
|
@ -58,54 +58,6 @@ def_package!(crate:MoreStringPackage:"Additional string utilities, including str
|
||||
|
||||
combine_with_exported_module!(lib, "string", string_functions);
|
||||
|
||||
lib.set_raw_fn(
|
||||
"pad",
|
||||
&[TypeId::of::<ImmutableString>(), TypeId::of::<INT>(), TypeId::of::<char>()],
|
||||
|_context, args| {
|
||||
let len = *args[1].read_lock::<INT>().unwrap();
|
||||
|
||||
// Check if string will be over max size limit
|
||||
#[cfg(not(feature = "unchecked"))]
|
||||
if _context.engine().max_string_size() > 0 && len > 0
|
||||
&& (len as usize) > _context.engine().max_string_size()
|
||||
{
|
||||
return EvalAltResult::ErrorDataTooLarge(
|
||||
"Length of string".to_string(),
|
||||
_context.engine().max_string_size(),
|
||||
len as usize,
|
||||
Position::none(),
|
||||
).into();
|
||||
}
|
||||
|
||||
if len > 0 {
|
||||
let ch = mem::take(args[2]).cast::<char>();
|
||||
let mut s = args[0].write_lock::<ImmutableString>().unwrap();
|
||||
|
||||
let orig_len = s.chars().count();
|
||||
|
||||
if len as usize > orig_len {
|
||||
let p = s.make_mut();
|
||||
|
||||
for _ in 0..(len as usize - orig_len) {
|
||||
p.push(ch);
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "unchecked"))]
|
||||
if _context.engine().max_string_size() > 0 && s.len() > _context.engine().max_string_size() {
|
||||
return EvalAltResult::ErrorDataTooLarge(
|
||||
"Length of string".to_string(),
|
||||
_context.engine().max_string_size(),
|
||||
s.len(),
|
||||
Position::none(),
|
||||
).into();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
},
|
||||
);
|
||||
|
||||
// Register string iterator
|
||||
lib.set_iter(
|
||||
TypeId::of::<ImmutableString>(),
|
||||
@ -176,7 +128,7 @@ mod string_functions {
|
||||
pub fn index_of_char_starting_from(s: &str, ch: char, start: INT) -> INT {
|
||||
let start = if start < 0 {
|
||||
0
|
||||
} else if (start as usize) >= s.chars().count() {
|
||||
} else if start as usize >= s.chars().count() {
|
||||
return -1 as INT;
|
||||
} else {
|
||||
s.chars().take(start as usize).collect::<String>().len()
|
||||
@ -197,7 +149,7 @@ mod string_functions {
|
||||
pub fn index_of_string_starting_from(s: &str, find: ImmutableString, start: INT) -> INT {
|
||||
let start = if start < 0 {
|
||||
0
|
||||
} else if (start as usize) >= s.chars().count() {
|
||||
} else if start as usize >= s.chars().count() {
|
||||
return -1 as INT;
|
||||
} else {
|
||||
s.chars().take(start as usize).collect::<String>().len()
|
||||
@ -220,7 +172,7 @@ mod string_functions {
|
||||
return "".to_string().into();
|
||||
} else if start < 0 {
|
||||
0
|
||||
} else if (start as usize) >= s.chars().count() {
|
||||
} else if start as usize >= s.chars().count() {
|
||||
return "".to_string().into();
|
||||
} else {
|
||||
start as usize
|
||||
@ -228,7 +180,7 @@ mod string_functions {
|
||||
|
||||
let chars: StaticVec<_> = s.chars().collect();
|
||||
|
||||
let len = if offset + (len as usize) > chars.len() {
|
||||
let len = if offset + len as usize > chars.len() {
|
||||
chars.len() - offset
|
||||
} else {
|
||||
len as usize
|
||||
@ -255,7 +207,7 @@ mod string_functions {
|
||||
return;
|
||||
} else if start < 0 {
|
||||
0
|
||||
} else if (start as usize) >= s.chars().count() {
|
||||
} else if start as usize >= s.chars().count() {
|
||||
s.make_mut().clear();
|
||||
return;
|
||||
} else {
|
||||
@ -264,7 +216,7 @@ mod string_functions {
|
||||
|
||||
let chars: StaticVec<_> = s.chars().collect();
|
||||
|
||||
let len = if offset + (len as usize) > chars.len() {
|
||||
let len = if offset + len as usize > chars.len() {
|
||||
chars.len() - offset
|
||||
} else {
|
||||
len as usize
|
||||
@ -295,6 +247,104 @@ mod string_functions {
|
||||
pub fn replace_char(s: &mut ImmutableString, find: char, sub: char) {
|
||||
*s = s.replace(&find.to_string(), &sub.to_string()).into();
|
||||
}
|
||||
#[rhai_fn(return_raw)]
|
||||
pub fn pad(
|
||||
_context: NativeCallContext,
|
||||
s: &mut ImmutableString,
|
||||
len: INT,
|
||||
ch: char,
|
||||
) -> Result<Dynamic, Box<EvalAltResult>> {
|
||||
// Check if string will be over max size limit
|
||||
#[cfg(not(feature = "unchecked"))]
|
||||
if _context.engine().max_string_size() > 0
|
||||
&& len as usize > _context.engine().max_string_size()
|
||||
{
|
||||
return EvalAltResult::ErrorDataTooLarge(
|
||||
"Length of string".to_string(),
|
||||
_context.engine().max_string_size(),
|
||||
len as usize,
|
||||
Position::none(),
|
||||
)
|
||||
.into();
|
||||
}
|
||||
|
||||
if len > 0 {
|
||||
let orig_len = s.chars().count();
|
||||
|
||||
if len as usize > orig_len {
|
||||
let p = s.make_mut();
|
||||
|
||||
for _ in 0..(len as usize - orig_len) {
|
||||
p.push(ch);
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "unchecked"))]
|
||||
if _context.engine().max_string_size() > 0
|
||||
&& s.len() > _context.engine().max_string_size()
|
||||
{
|
||||
return EvalAltResult::ErrorDataTooLarge(
|
||||
"Length of string".to_string(),
|
||||
_context.engine().max_string_size(),
|
||||
s.len(),
|
||||
Position::none(),
|
||||
)
|
||||
.into();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(().into())
|
||||
}
|
||||
#[rhai_fn(name = "pad", return_raw)]
|
||||
pub fn pad_with_string(
|
||||
_context: NativeCallContext,
|
||||
s: &mut ImmutableString,
|
||||
len: INT,
|
||||
padding: &str,
|
||||
) -> Result<Dynamic, Box<EvalAltResult>> {
|
||||
// Check if string will be over max size limit
|
||||
#[cfg(not(feature = "unchecked"))]
|
||||
if _context.engine().max_string_size() > 0
|
||||
&& len as usize > _context.engine().max_string_size()
|
||||
{
|
||||
return EvalAltResult::ErrorDataTooLarge(
|
||||
"Length of string".to_string(),
|
||||
_context.engine().max_string_size(),
|
||||
len as usize,
|
||||
Position::none(),
|
||||
)
|
||||
.into();
|
||||
}
|
||||
|
||||
if len > 0 {
|
||||
let mut str_len = s.chars().count();
|
||||
let padding_len = padding.chars().count();
|
||||
|
||||
if len as usize > str_len {
|
||||
let p = s.make_mut();
|
||||
|
||||
while str_len < len as usize {
|
||||
p.push_str(padding);
|
||||
str_len += padding_len;
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "unchecked"))]
|
||||
if _context.engine().max_string_size() > 0
|
||||
&& s.len() > _context.engine().max_string_size()
|
||||
{
|
||||
return EvalAltResult::ErrorDataTooLarge(
|
||||
"Length of string".to_string(),
|
||||
_context.engine().max_string_size(),
|
||||
s.len(),
|
||||
Position::none(),
|
||||
)
|
||||
.into();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(().into())
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "no_index"))]
|
||||
pub mod arrays {
|
||||
|
Loading…
Reference in New Issue
Block a user