Improve string parameters.

This commit is contained in:
Stephen Chung 2022-02-24 13:39:10 +08:00
parent 39ef766bf1
commit d2ad56e279
3 changed files with 81 additions and 31 deletions

View File

@ -241,7 +241,7 @@ pub mod blob_functions {
/// print(b); // prints "[424242424268656c 6c6f]" /// print(b); // prints "[424242424268656c 6c6f]"
/// ``` /// ```
#[rhai_fn(name = "+=", name = "append")] #[rhai_fn(name = "+=", name = "append")]
pub fn append_str(blob: &mut Blob, string: ImmutableString) { pub fn append_str(blob: &mut Blob, string: &str) {
if !string.is_empty() { if !string.is_empty() {
blob.extend(string.as_bytes()); blob.extend(string.as_bytes());
} }

View File

@ -22,16 +22,16 @@ def_package! {
mod string_functions { mod string_functions {
use crate::{ImmutableString, SmartString}; use crate::{ImmutableString, SmartString};
#[rhai_fn(name = "+")] #[rhai_fn(name = "+", pure)]
pub fn add_append( pub fn add_append(
ctx: NativeCallContext, ctx: NativeCallContext,
string: ImmutableString, string: &mut ImmutableString,
mut item: Dynamic, mut item: Dynamic,
) -> ImmutableString { ) -> ImmutableString {
let s = print_with_func(FUNC_TO_STRING, &ctx, &mut item); let s = print_with_func(FUNC_TO_STRING, &ctx, &mut item);
if s.is_empty() { if s.is_empty() {
string string.clone()
} else { } else {
format!("{}{}", string, s).into() format!("{}{}", string, s).into()
} }
@ -61,16 +61,16 @@ mod string_functions {
// The following are needed in order to override the generic versions with `Dynamic` parameters. // The following are needed in order to override the generic versions with `Dynamic` parameters.
#[rhai_fn(name = "+")] #[rhai_fn(name = "+", pure)]
pub fn add_append_str(string1: ImmutableString, string2: ImmutableString) -> ImmutableString { pub fn add_append_str(string1: &mut ImmutableString, string2: &str) -> ImmutableString {
string1 + string2 &*string1 + string2
}
#[rhai_fn(name = "+", pure)]
pub fn add_append_char(string: &mut ImmutableString, character: char) -> ImmutableString {
&*string + character
} }
#[rhai_fn(name = "+")] #[rhai_fn(name = "+")]
pub fn add_append_char(string: ImmutableString, character: char) -> ImmutableString { pub fn add_prepend_char(character: char, string: &str) -> ImmutableString {
string + character
}
#[rhai_fn(name = "+")]
pub fn add_prepend_char(character: char, string: ImmutableString) -> ImmutableString {
format!("{}{}", character, string).into() format!("{}{}", character, string).into()
} }
@ -86,14 +86,14 @@ mod string_functions {
#[cfg(not(feature = "no_index"))] #[cfg(not(feature = "no_index"))]
pub mod blob_functions { pub mod blob_functions {
#[rhai_fn(name = "+")] #[rhai_fn(name = "+", pure)]
pub fn add_append_blob(string: ImmutableString, utf8: Blob) -> ImmutableString { pub fn add_append_blob(string: &mut ImmutableString, utf8: Blob) -> ImmutableString {
if utf8.is_empty() { if utf8.is_empty() {
string string.clone()
} else if string.is_empty() { } else if string.is_empty() {
String::from_utf8_lossy(&utf8).into_owned().into() String::from_utf8_lossy(&utf8).into_owned().into()
} else { } else {
let mut s = crate::SmartString::from(string); let mut s = crate::SmartString::from(string.as_str());
s.push_str(&String::from_utf8_lossy(&utf8)); s.push_str(&String::from_utf8_lossy(&utf8));
s.into() s.into()
} }
@ -172,7 +172,7 @@ mod string_functions {
/// ///
/// print(text); // prints ", world! , foobar!" /// print(text); // prints ", world! , foobar!"
/// ``` /// ```
pub fn remove(string: &mut ImmutableString, sub_string: ImmutableString) { pub fn remove(string: &mut ImmutableString, sub_string: &str) {
*string -= sub_string; *string -= sub_string;
} }
/// Remove all occurrences of a character from the string. /// Remove all occurrences of a character from the string.
@ -263,7 +263,7 @@ mod string_functions {
} }
} }
} }
/// Remove the a specified number of characters from the end of the string and return it as a /// Remove a specified number of characters from the end of the string and return it as a
/// new string. /// new string.
/// ///
/// * If `len` ≤ 0, the string is not modified and an empty string is returned. /// * If `len` ≤ 0, the string is not modified and an empty string is returned.
@ -311,9 +311,10 @@ mod string_functions {
/// ///
/// print(text); // prints "hello, world!" /// print(text); // prints "hello, world!"
/// ``` /// ```
pub fn to_upper(string: ImmutableString) -> ImmutableString { #[rhai_fn(pure)]
if string.is_empty() { pub fn to_upper(string: &mut ImmutableString) -> ImmutableString {
string if string.is_empty() || string.chars().all(char::is_uppercase) {
string.clone()
} else { } else {
string.to_uppercase().into() string.to_uppercase().into()
} }
@ -330,7 +331,7 @@ mod string_functions {
/// print(text); // prints "HELLO, WORLD!"; /// print(text); // prints "HELLO, WORLD!";
/// ``` /// ```
pub fn make_upper(string: &mut ImmutableString) { pub fn make_upper(string: &mut ImmutableString) {
if !string.is_empty() { if !string.is_empty() && string.chars().any(|ch| !ch.is_uppercase()) {
*string = string.to_uppercase().into(); *string = string.to_uppercase().into();
} }
} }
@ -345,9 +346,10 @@ mod string_functions {
/// ///
/// print(text); // prints "HELLO, WORLD!" /// print(text); // prints "HELLO, WORLD!"
/// ``` /// ```
pub fn to_lower(string: ImmutableString) -> ImmutableString { #[rhai_fn(pure)]
if string.is_empty() { pub fn to_lower(string: &mut ImmutableString) -> ImmutableString {
string if string.is_empty() || string.chars().all(char::is_lowercase) {
string.clone()
} else { } else {
string.to_lowercase().into() string.to_lowercase().into()
} }
@ -364,7 +366,7 @@ mod string_functions {
/// print(text); // prints "hello, world!"; /// print(text); // prints "hello, world!";
/// ``` /// ```
pub fn make_lower(string: &mut ImmutableString) { pub fn make_lower(string: &mut ImmutableString) {
if !string.is_empty() { if !string.is_empty() && string.chars().any(|ch| !ch.is_lowercase()) {
*string = string.to_lowercase().into(); *string = string.to_lowercase().into();
} }
} }
@ -1204,19 +1206,25 @@ mod string_functions {
/// print(text.split(-99)); // prints ["", "hello, world!"] /// print(text.split(-99)); // prints ["", "hello, world!"]
/// ``` /// ```
#[rhai_fn(name = "split")] #[rhai_fn(name = "split")]
pub fn split_at(ctx: NativeCallContext, string: ImmutableString, index: INT) -> Array { pub fn split_at(ctx: NativeCallContext, string: &mut ImmutableString, index: INT) -> Array {
if index <= 0 { if index <= 0 {
if let Some(n) = index.checked_abs() { if let Some(n) = index.checked_abs() {
let num_chars = string.chars().count(); let num_chars = string.chars().count();
if n as usize > num_chars { if n as usize > num_chars {
vec![ctx.engine().const_empty_string().into(), string.into()] vec![
ctx.engine().const_empty_string().into(),
string.as_str().into(),
]
} else { } else {
let prefix: String = string.chars().take(num_chars - n as usize).collect(); let prefix: String = string.chars().take(num_chars - n as usize).collect();
let prefix_len = prefix.len(); let prefix_len = prefix.len();
vec![prefix.into(), string[prefix_len..].into()] vec![prefix.into(), string[prefix_len..].into()]
} }
} else { } else {
vec![ctx.engine().const_empty_string().into(), string.into()] vec![
ctx.engine().const_empty_string().into(),
string.as_str().into(),
]
} }
} else { } else {
let prefix: String = string.chars().take(index as usize).collect(); let prefix: String = string.chars().take(index as usize).collect();

View File

@ -459,8 +459,50 @@ impl Sub<String> for &ImmutableString {
impl SubAssign<String> for ImmutableString { impl SubAssign<String> for ImmutableString {
#[inline] #[inline]
fn sub_assign(&mut self, rhs: String) { fn sub_assign(&mut self, rhs: String) {
let rhs: SmartString = self.replace(&rhs, "").into(); if !rhs.is_empty() {
self.0 = rhs.into(); let rhs: SmartString = self.replace(&rhs, "").into();
self.0 = rhs.into();
}
}
}
impl Sub<&str> for ImmutableString {
type Output = Self;
#[inline]
fn sub(self, rhs: &str) -> Self::Output {
if rhs.is_empty() {
self
} else if self.is_empty() {
rhs.into()
} else {
self.replace(rhs, "").into()
}
}
}
impl Sub<&str> for &ImmutableString {
type Output = ImmutableString;
#[inline]
fn sub(self, rhs: &str) -> Self::Output {
if rhs.is_empty() {
self.clone()
} else if self.is_empty() {
rhs.into()
} else {
self.replace(rhs, "").into()
}
}
}
impl SubAssign<&str> for ImmutableString {
#[inline]
fn sub_assign(&mut self, rhs: &str) {
if !rhs.is_empty() {
let rhs: SmartString = self.replace(rhs, "").into();
self.0 = rhs.into();
}
} }
} }