Add string::split().

This commit is contained in:
Stephen Chung 2020-09-25 23:02:49 +08:00
parent da9aa60256
commit 4efe6b90e7
3 changed files with 39 additions and 7 deletions

View File

@ -16,6 +16,7 @@ using a [raw `Engine`]) operate on [strings]:
| `contains` | character/sub-string to search for | checks if a certain character or sub-string occurs in the string | | `contains` | character/sub-string to search for | checks if a certain character or sub-string occurs in the string |
| `index_of` | character/sub-string to search for, start index _(optional)_ | returns the index that a certain character or sub-string occurs in the string, or -1 if not found | | `index_of` | character/sub-string to search for, start index _(optional)_ | returns the index that a certain character or sub-string occurs in the string, or -1 if not found |
| `sub_string` | start index, length _(optional)_ | extracts a sub-string (to the end of the string if length is not specified) | | `sub_string` | start index, length _(optional)_ | extracts a sub-string (to the end of the string if length is not specified) |
| `split` | delimiter character/string | splits the string by the specified delimiter, returning an [array] of string segments |
| `crop` | start index, length _(optional)_ | retains only a portion of the string (to the end of the string if length is not specified) | | `crop` | start index, length _(optional)_ | retains only a portion of the string (to the end of the string if length is not specified) |
| `replace` | target character/sub-string, replacement character/string | replaces a sub-string with another | | `replace` | target character/sub-string, replacement character/string | replaces a sub-string with another |
| `trim` | _none_ | trims the string of whitespace at the beginning and end | | `trim` | _none_ | trims the string of whitespace at the beginning and end |

View File

@ -187,9 +187,8 @@ mod string_functions {
pub fn contains_char(s: &str, ch: char) -> bool { pub fn contains_char(s: &str, ch: char) -> bool {
s.contains(ch) s.contains(ch)
} }
#[rhai_fn(name = "contains")]
#[inline(always)] #[inline(always)]
pub fn contains_string(s: &str, find: ImmutableString) -> bool { pub fn contains(s: &str, find: ImmutableString) -> bool {
s.contains(find.as_str()) s.contains(find.as_str())
} }
@ -230,13 +229,12 @@ mod string_functions {
.unwrap_or(-1 as INT) .unwrap_or(-1 as INT)
} }
#[rhai_fn(name = "index_of")] #[rhai_fn(name = "index_of")]
pub fn index_of_string(s: &str, find: ImmutableString) -> INT { pub fn index_of(s: &str, find: ImmutableString) -> INT {
s.find(find.as_str()) s.find(find.as_str())
.map(|index| s[0..index].chars().count() as INT) .map(|index| s[0..index].chars().count() as INT)
.unwrap_or(-1 as INT) .unwrap_or(-1 as INT)
} }
#[rhai_fn(name = "sub_string")]
pub fn sub_string(s: &str, start: INT, len: INT) -> ImmutableString { pub fn sub_string(s: &str, start: INT, len: INT) -> ImmutableString {
let offset = if s.is_empty() || len <= 0 { let offset = if s.is_empty() || len <= 0 {
return "".to_string().into(); return "".to_string().into();
@ -272,7 +270,7 @@ mod string_functions {
} }
#[rhai_fn(name = "crop")] #[rhai_fn(name = "crop")]
pub fn crop_string(s: &mut ImmutableString, start: INT, len: INT) { pub fn crop(s: &mut ImmutableString, start: INT, len: INT) {
let offset = if s.is_empty() || len <= 0 { let offset = if s.is_empty() || len <= 0 {
s.make_mut().clear(); s.make_mut().clear();
return; return;
@ -300,12 +298,12 @@ mod string_functions {
#[rhai_fn(name = "crop")] #[rhai_fn(name = "crop")]
#[inline(always)] #[inline(always)]
pub fn crop_string_starting_from(s: &mut ImmutableString, start: INT) { pub fn crop_string_starting_from(s: &mut ImmutableString, start: INT) {
crop_string(s, start, s.len() as INT); crop(s, start, s.len() as INT);
} }
#[rhai_fn(name = "replace")] #[rhai_fn(name = "replace")]
#[inline(always)] #[inline(always)]
pub fn replace_string(s: &mut ImmutableString, find: ImmutableString, sub: ImmutableString) { pub fn replace(s: &mut ImmutableString, find: ImmutableString, sub: ImmutableString) {
*s = s.replace(find.as_str(), sub.as_str()).into(); *s = s.replace(find.as_str(), sub.as_str()).into();
} }
#[rhai_fn(name = "replace")] #[rhai_fn(name = "replace")]
@ -338,6 +336,18 @@ mod string_functions {
pub fn prepend(x: &mut Array, y: &str) -> String { pub fn prepend(x: &mut Array, y: &str) -> String {
format!("{:?}{}", x, y) format!("{:?}{}", x, y)
} }
#[inline(always)]
pub fn split(s: &str, delimiter: ImmutableString) -> Array {
s.split(delimiter.as_str())
.map(Into::<Dynamic>::into)
.collect()
}
#[rhai_fn(name = "split")]
#[inline(always)]
pub fn split_char(s: &str, delimiter: char) -> Array {
s.split(delimiter).map(Into::<Dynamic>::into).collect()
}
} }
#[cfg(not(feature = "no_object"))] #[cfg(not(feature = "no_object"))]

View File

@ -186,3 +186,24 @@ fn test_string_fn() -> Result<(), Box<EvalAltResult>> {
Ok(()) Ok(())
} }
#[cfg(not(feature = "no_object"))]
#[test]
fn test_string_split() -> Result<(), Box<EvalAltResult>> {
let engine = Engine::new();
assert_eq!(
engine.eval::<INT>(
r#"let x = "\u2764\u2764\u2764 hello! \u2764\u2764\u2764"; x.split(' ').len"#
)?,
3
);
assert_eq!(
engine.eval::<INT>(
r#"let x = "\u2764\u2764\u2764 hello! \u2764\u2764\u2764"; x.split("hello").len"#
)?,
2
);
Ok(())
}