diff --git a/README.md b/README.md index 4fb86ec8..eee7c1c9 100644 --- a/README.md +++ b/README.md @@ -179,13 +179,14 @@ A number of examples can be found in the `examples` folder: | Example | Description | | ------------------------------------------------------------------ | --------------------------------------------------------------------------- | -| [`arrays_and_structs`](examples/arrays_and_structs.rs) | demonstrates registering a new type to Rhai and the usage of [arrays] on it | -| [`custom_types_and_methods`](examples/custom_types_and_methods.rs) | shows how to register a type and methods for it | +| [`arrays_and_structs`](examples/arrays_and_structs.rs) | shows how to register a custom Rust type and using [arrays] on it | +| [`custom_types_and_methods`](examples/custom_types_and_methods.rs) | shows how to register a custom Rust type and methods for it | | [`hello`](examples/hello.rs) | simple example that evaluates an expression and prints the result | | [`no_std`](examples/no_std.rs) | example to test out `no-std` builds | | [`reuse_scope`](examples/reuse_scope.rs) | evaluates two pieces of code in separate runs, but using a common [`Scope`] | | [`rhai_runner`](examples/rhai_runner.rs) | runs each filename passed to it as a Rhai script | -| [`simple_fn`](examples/simple_fn.rs) | shows how to register a Rust function to a Rhai [`Engine`] | +| [`simple_fn`](examples/simple_fn.rs) | shows how to register a simple function | +| [`strings`](examples/strings.rs) | shows different ways to register functions taking string arguments | | [`repl`](examples/repl.rs) | a simple REPL, interactively evaluate statements from stdin | Examples can be run with the following command: diff --git a/examples/strings.rs b/examples/strings.rs new file mode 100644 index 00000000..9e874377 --- /dev/null +++ b/examples/strings.rs @@ -0,0 +1,79 @@ +///! This example registers a variety of functions that operate on strings. +///! Remember to use `ImmutableString` or `&str` instead of `String` as parameters. +use rhai::{Engine, EvalAltResult, ImmutableString, RegisterFn, Scope, INT}; +use std::io::{stdin, stdout, Write}; + +/// Trim whitespace from a string. The original string argument is changed. +/// +/// This version uses `&mut ImmutableString` +fn trim_string(s: &mut ImmutableString) { + *s = s.trim().into(); +} + +/// Notice this is different from the built-in Rhai 'len' function for strings +/// which counts the actual number of Unicode _characters_ in a string. +/// This version simply counts the number of _bytes_ in the UTF-8 representation. +/// +/// This version uses `&str`. +fn count_string_bytes(s: &str) -> INT { + s.len() as INT +} + +/// This version uses `ImmutableString` and `&str`. +fn find_substring(s: ImmutableString, sub: &str) -> INT { + s.as_str().find(sub).map(|x| x as INT).unwrap_or(-1) +} + +fn main() -> Result<(), Box> { + // Create a `raw` Engine with no built-in string functions. + let mut engine = Engine::new_raw(); + + // Register string functions + engine.register_fn("trim", trim_string); + engine.register_fn("len", count_string_bytes); + engine.register_fn("index_of", find_substring); + + // Register string functions using closures + engine.register_fn("display", |label: &str, x: INT| { + println!("{}: {}", label, x) + }); + engine.register_fn("display", |label: ImmutableString, x: &str| { + println!(r#"{}: "{}""#, label, x) // Quote the input string + }); + + let mut scope = Scope::new(); + let mut input = String::new(); + + loop { + scope.clear(); + + println!("Type something. Press Ctrl-C to exit."); + print!("strings> "); + stdout().flush().expect("couldn't flush stdout"); + + input.clear(); + + if let Err(err) = stdin().read_line(&mut input) { + panic!("input error: {}", err); + } + + scope.push("x", input.clone()); + + println!("Line: {}", input.replace('\r', "\\r").replace('\n', "\\n")); + + engine.consume_with_scope( + &mut scope, + r#" + display("Length", x.len()); + x.trim(); + display("Trimmed", x); + display("Trimmed Length", x.len()); + display("Index of \"!!!\"", x.index_of("!!!")); + "#, + )?; + + println!(); + } + + Ok(()) +} diff --git a/src/engine.rs b/src/engine.rs index 4ad31b36..0408d50f 100644 --- a/src/engine.rs +++ b/src/engine.rs @@ -228,7 +228,7 @@ pub fn get_script_function_by_signature<'a>( /// # } /// ``` /// -/// Currently, `Engine` is neither `Send` nor `Sync`. Turn on the `sync` feature to make it `Send + Sync`. +/// Currently, `Engine` is neither `Send` nor `Sync`. Use the `sync` feature to make it `Send + Sync`. pub struct Engine { /// A module containing all functions directly loaded into the Engine. pub(crate) global_module: Module,