diff --git a/doc/src/engine/raw.md b/doc/src/engine/raw.md
index cf867246..e5add617 100644
--- a/doc/src/engine/raw.md
+++ b/doc/src/engine/raw.md
@@ -17,12 +17,12 @@ To add more functionalities to a _raw_ `Engine`, load [packages] into it.
Built-in Operators
------------------
-| Operators | Assignment operators | Supported for types (see [standard types]) |
-| ------------------------ | ---------------------------- | ----------------------------------------------------------------------------- |
-| `+`, | `+=` | `INT`, `FLOAT` (if not [`no_float`]), `ImmutableString` |
-| `-`, `*`, `/`, `%`, `~`, | `-=`, `*=`, `/=`, `%=`, `~=` | `INT`, `FLOAT` (if not [`no_float`]) |
-| `<<`, `>>`, `^`, | `<<=`, `>>=`, `^=` | `INT` |
-| `&`, \|
, | `&=`, \|=
| `INT`, `bool` |
-| `&&`, \|\|
| | `bool` |
-| `==`, `!=` | | `INT`, `FLOAT` (if not [`no_float`]), `bool`, `char`, `()`, `ImmutableString` |
-| `>`, `>=`, `<`, `<=` | | `INT`, `FLOAT` (if not [`no_float`]), `char`, `()`, `ImmutableString` |
+| Operators | Assignment operators | Supported for types (see [standard types]) |
+| ------------------------- | ---------------------------- | ----------------------------------------------------------------------------- |
+| `+`, | `+=` | `INT`, `FLOAT` (if not [`no_float`]), `char`, `ImmutableString` |
+| `-`, `*`, `/`, `%`, `~`, | `-=`, `*=`, `/=`, `%=`, `~=` | `INT`, `FLOAT` (if not [`no_float`]) |
+| `<<`, `>>` | `<<=`, `>>=` | `INT` |
+| `&`, \|
, `^` | `&=`, \|=
, `^=` | `INT`, `bool` |
+| `&&`, \|\|
| | `bool` |
+| `==`, `!=` | | `INT`, `FLOAT` (if not [`no_float`]), `bool`, `char`, `()`, `ImmutableString` |
+| `>`, `>=`, `<`, `<=` | | `INT`, `FLOAT` (if not [`no_float`]), `char`, `()`, `ImmutableString` |
diff --git a/doc/src/rust/print-custom.md b/doc/src/rust/print-custom.md
index 2aab1b92..2ea6f1e8 100644
--- a/doc/src/rust/print-custom.md
+++ b/doc/src/rust/print-custom.md
@@ -7,11 +7,11 @@ To use custom types for [`print`] and [`debug`], or convert its value into a [st
it is necessary that the following functions be registered (assuming the custom type
is `T : Display + Debug`):
-| Function | Signature | Typical implementation | Usage |
-| ----------- | ------------------------------------------------------------- | ------------------------------------- | ---------------------------------------------------------------------------------------- |
-| `to_string` | \|s: &mut T\| -> ImmutableString
| `s.to_string().into()` | converts the custom type into a [string] |
-| `print` | \|s: &mut T\| -> ImmutableString
| `s.to_string().into()` | converts the custom type into a [string] for the [`print`] statement |
-| `debug` | \|s: &mut T\| -> ImmutableString
| `format!("{:?}", s).into()` | converts the custom type into a [string] for the [`debug`] statement |
-| `+` | \|s1: ImmutableString, s: T\| -> ImmutableString
| `s1 + s` | appends the custom type to another [string], for `print("Answer: " + type);` usage |
-| `+` | \|s: T, s2: ImmutableString\| -> ImmutableString
| `s.to_string().push_str(&s2).into();` | appends another [string] to the custom type, for `print(type + " is the answer");` usage |
-| `+=` | \|s1: &mut ImmutableString, s: T\|
| `s1 += s.to_string()` | appends the custom type to an existing [string], for `s += type;` usage |
+| Function | Signature | Typical implementation | Usage |
+| ----------- | ---------------------------------------------- | ---------------------------- | -------------------------------------------------------------------- |
+| `to_string` | \|x: &mut T\| -> String
| `x.to_string()` | converts the custom type into a [string] |
+| `print` | \|x: &mut T\| -> String
| `x.to_string()` | converts the custom type into a [string] for the [`print`] statement |
+| `debug` | \|x: &mut T\| -> String
| `format!("{:?}", x)` | converts the custom type into a [string] for the [`debug`] statement |
+| `+` | \|s: &str, x: T\| -> String
| `format!("{}{}", s, x)` | concatenates the custom type with another [string] |
+| `+` | \|x: &mut T, s: &str\| -> String
| `x.to_string().push_str(s);` | concatenates another [string] with the custom type |
+| `+=` | \|s: &mut ImmutableString, x: T\|
| `s += x.to_string()` | appends the custom type to an existing [string] |
diff --git a/src/fn_call.rs b/src/fn_call.rs
index 7dc97319..832e696c 100644
--- a/src/fn_call.rs
+++ b/src/fn_call.rs
@@ -1239,8 +1239,28 @@ pub fn run_builtin_binary_op(
use crate::packages::arithmetic::arith_basic::INT::functions::*;
let args_type = x.type_id();
+ let second_type = y.type_id();
- if y.type_id() != args_type {
+ if second_type != args_type {
+ if args_type == TypeId::of::() && second_type == TypeId::of::() {
+ let x = x.clone().cast::();
+ let y = &*y.read_lock::().unwrap();
+
+ match op {
+ "+" => return Ok(Some(format!("{}{}", x, y).into())),
+ _ => (),
+ }
+ } else if args_type == TypeId::of::()
+ && second_type == TypeId::of::()
+ {
+ let x = &*x.read_lock::().unwrap();
+ let y = y.clone().cast::();
+
+ match op {
+ "+" => return Ok(Some((x + y).into())),
+ _ => (),
+ }
+ }
return Ok(None);
}
@@ -1317,6 +1337,7 @@ pub fn run_builtin_binary_op(
let y = y.clone().cast::();
match op {
+ "+" => return Ok(Some(format!("{}{}", x, y).into())),
"==" => return Ok(Some((x == y).into())),
"!=" => return Ok(Some((x != y).into())),
">" => return Ok(Some((x > y).into())),
@@ -1367,8 +1388,19 @@ pub fn run_builtin_op_assignment(
use crate::packages::arithmetic::arith_basic::INT::functions::*;
let args_type = x.type_id();
+ let second_type = y.type_id();
+
+ if second_type != args_type {
+ if args_type == TypeId::of::() && second_type == TypeId::of::() {
+ let y = y.read_lock::().unwrap().deref().clone();
+ let mut x = x.write_lock::().unwrap();
+
+ match op {
+ "+=" => return Ok(Some(*x += y)),
+ _ => (),
+ }
+ }
- if y.type_id() != args_type {
return Ok(None);
}
@@ -1417,6 +1449,14 @@ pub fn run_builtin_op_assignment(
"|=" => return Ok(Some(*x = *x || y)),
_ => (),
}
+ } else if args_type == TypeId::of::() {
+ let y = y.read_lock::().unwrap().deref().clone();
+ let mut x = x.write_lock::().unwrap();
+
+ match op {
+ "+=" => return Ok(Some(*x = format!("{}{}", *x, y).into())),
+ _ => (),
+ }
} else if args_type == TypeId::of::() {
let y = y.read_lock::().unwrap().deref().clone();
let mut x = x.write_lock::().unwrap();
diff --git a/src/packages/string_more.rs b/src/packages/string_more.rs
index e89e03f8..c799e221 100644
--- a/src/packages/string_more.rs
+++ b/src/packages/string_more.rs
@@ -43,7 +43,7 @@ macro_rules! reg_functions {
}
def_package!(crate:MoreStringPackage:"Additional string utilities, including string building.", lib, {
- reg_functions!(lib += basic; INT, bool, char, FnPtr);
+ reg_functions!(lib += basic; INT, bool, FnPtr);
#[cfg(not(feature = "only_i32"))]
#[cfg(not(feature = "only_i64"))]
@@ -139,15 +139,6 @@ mod string_functions {
s
}
- #[rhai_fn(name = "+=")]
- pub fn append_char(s: &mut ImmutableString, ch: char) {
- *s += ch;
- }
- #[rhai_fn(name = "+=")]
- pub fn append_string(s: &mut ImmutableString, add: ImmutableString) {
- *s += &add;
- }
-
#[rhai_fn(name = "len", get = "len")]
pub fn len(s: &str) -> INT {
s.chars().count() as INT