Add splitn, rsplit and rsplitn equivalents to strings.

This commit is contained in:
Stephen Chung 2021-02-23 11:56:04 +08:00
parent 7f0d7f1bc7
commit ac3d8e35d4
3 changed files with 60 additions and 2 deletions

View File

@ -29,6 +29,7 @@ Enhancements
* Error position in `eval` statements is now wrapped in an `EvalAltResult::ErrorInFunctionCall`.
* `Position` now implements `Add` and `AddAssign`.
* `Scope` now implements `IntoIterator`.
* Strings now have the `split_rev` method and variations of `split` with maximum number of segments.
Version 0.19.12

View File

@ -627,7 +627,7 @@ pub struct Limits {
/// Context of a script evaluation process.
#[derive(Debug)]
pub struct EvalContext<'e, 'x, 'px: 'x, 'a, 's, 'm, 't, 'pt: 't> {
pub struct EvalContext<'e, 'x, 'px, 'a, 's, 'm, 't, 'pt> {
pub(crate) engine: &'e Engine,
pub(crate) scope: &'x mut Scope<'px>,
pub(crate) mods: &'a mut Imports,

View File

@ -360,7 +360,8 @@ mod string_functions {
#[cfg(not(feature = "no_index"))]
pub mod arrays {
use crate::Array;
use crate::stdlib::vec;
use crate::{Array, ImmutableString};
#[rhai_fn(name = "+")]
pub fn append(string: &str, array: Array) -> String {
@ -370,13 +371,69 @@ mod string_functions {
pub fn prepend(array: &mut Array, string: &str) -> String {
format!("{:?}{}", array, string)
}
#[rhai_fn(name = "split")]
pub fn split_at(string: ImmutableString, start: INT) -> Array {
if start <= 0 {
vec!["".into(), string.into()]
} else {
let prefix: String = string.chars().take(start as usize).collect();
let prefix_len = prefix.len();
vec![prefix.into(), string[prefix_len..].into()]
}
}
pub fn split(string: &str, delimiter: &str) -> Array {
string.split(delimiter).map(Into::<Dynamic>::into).collect()
}
#[rhai_fn(name = "split")]
pub fn splitn(string: &str, delimiter: &str, segments: INT) -> Array {
let pieces: usize = if segments < 1 { 1 } else { segments as usize };
string
.splitn(pieces, delimiter)
.map(Into::<Dynamic>::into)
.collect()
}
#[rhai_fn(name = "split")]
pub fn split_char(string: &str, delimiter: char) -> Array {
string.split(delimiter).map(Into::<Dynamic>::into).collect()
}
#[rhai_fn(name = "split")]
pub fn splitn_char(string: &str, delimiter: char, segments: INT) -> Array {
let pieces: usize = if segments < 1 { 1 } else { segments as usize };
string
.splitn(pieces, delimiter)
.map(Into::<Dynamic>::into)
.collect()
}
#[rhai_fn(name = "split_rev")]
pub fn rsplit(string: &str, delimiter: &str) -> Array {
string
.rsplit(delimiter)
.map(Into::<Dynamic>::into)
.collect()
}
#[rhai_fn(name = "split_rev")]
pub fn rsplitn(string: &str, delimiter: &str, segments: INT) -> Array {
let pieces: usize = if segments < 1 { 1 } else { segments as usize };
string
.rsplitn(pieces, delimiter)
.map(Into::<Dynamic>::into)
.collect()
}
#[rhai_fn(name = "split_rev")]
pub fn rsplit_char(string: &str, delimiter: char) -> Array {
string
.rsplit(delimiter)
.map(Into::<Dynamic>::into)
.collect()
}
#[rhai_fn(name = "split_rev")]
pub fn rsplitn_char(string: &str, delimiter: char, segments: INT) -> Array {
let pieces: usize = if segments < 1 { 1 } else { segments as usize };
string
.rsplitn(pieces, delimiter)
.map(Into::<Dynamic>::into)
.collect()
}
}
#[cfg(not(feature = "no_object"))]