use rhai::{Engine, EvalAltResult, ImmutableString, Scope};
use std::io::{stdin, stdout, Write};
fn trim_string(s: &mut ImmutableString) {
*s = s.trim().into();
}
fn count_string_bytes(s: &str) -> i64 {
s.len() as i64
}
fn find_substring(s: ImmutableString, sub: &str) -> i64 {
s.find(sub).map(|x| x as i64).unwrap_or(-1)
}
fn main() -> Result<(), Box<EvalAltResult>> {
let mut engine = Engine::new_raw();
engine
.register_fn("trim", trim_string)
.register_fn("len", count_string_bytes)
.register_fn("index_of", find_substring)
.register_fn("display", |label: &str, value: i64| {
println!("{}: {}", label, value)
})
.register_fn("display", |label: ImmutableString, value: &str| {
println!(r#"{}: "{}""#, label, value) });
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.run_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!();
}
}