diff --git a/src/engine.rs b/src/engine.rs index ba67c959..e18b9386 100644 --- a/src/engine.rs +++ b/src/engine.rs @@ -91,14 +91,44 @@ pub enum FnType { InternalFn(FnDef), } +/// Rhai's engine type. This is what you use to run Rhai scripts +/// +/// ```rust +/// extern crate rhai; +/// use rhai::Engine; +/// +/// fn main() { +/// let mut engine = Engine::new(); +/// +/// if let Ok(result) = engine.eval::("40 + 2") { +/// println!("Answer: {}", result); // prints 42 +/// } +/// } +/// ``` pub struct Engine { pub fns: HashMap>, } +/// A type containing information about current scope. +/// Useful for keeping state between `Engine` runs +/// +/// ```rust +/// use rhai::{Engine, Scope}; +/// +/// let mut engine = Engine::new(); +/// let mut my_scope = Scope::new(); +/// +/// assert!(engine.eval_with_scope::<()>(&mut my_scope, "let x = 5;").is_ok()); +/// assert_eq!(engine.eval_with_scope::(&mut my_scope, "x + 1").unwrap(), 6); +/// ``` +/// +/// Between runs, `Engine` only remembers functions when not using own `Scope`. pub type Scope = Vec<(String, Box)>; impl Engine { - fn call_fn(&self, + /// Universal method for calling functions, that are either + /// registered with the `Engine` or written in Rhai + pub fn call_fn(&self, name: &str, arg1: Option<&mut Box>, arg2: Option<&mut Box>, @@ -500,6 +530,8 @@ impl Engine { } } + /// Register a type for use with Engine. Keep in mind that + /// your type must implement Clone. pub fn register_type(&mut self) { fn clone_helper(t: T) -> T { t.clone() @@ -508,6 +540,7 @@ impl Engine { self.register_fn("clone", clone_helper as fn(T) -> T); } + /// Register a get function for a member of a registered type pub fn register_get(&mut self, name: &str, get_fn: F) where F: 'static + Fn(&mut T) -> U { @@ -516,6 +549,7 @@ impl Engine { self.register_fn(&get_name, get_fn); } + /// Register a set function for a member of a registered type pub fn register_set(&mut self, name: &str, set_fn: F) where F: 'static + Fn(&mut T, U) -> () { @@ -524,6 +558,7 @@ impl Engine { self.register_fn(&set_name, set_fn); } + /// Shorthand for registering both getters and setters pub fn register_get_set(&mut self, name: &str, get_fn: F, @@ -1187,6 +1222,7 @@ impl Engine { } } + /// Evaluate a file pub fn eval_file(&mut self, fname: &str) -> Result { use std::fs::File; use std::io::prelude::*; @@ -1204,12 +1240,14 @@ impl Engine { } } + /// Evaluate a string pub fn eval(&mut self, input: &str) -> Result { let mut scope: Scope = Vec::new(); self.eval_with_scope(&mut scope, input) } + /// Evaluate with own scope pub fn eval_with_scope(&mut self, scope: &mut Scope, input: &str) @@ -1254,6 +1292,9 @@ impl Engine { } } + /// Evaluate a file, but only return errors, if there are any. + /// Useful for when you don't need the result, but still need + /// to keep track of possible errors pub fn consume_file(&mut self, fname: &str) -> Result<(), EvalAltResult> { use std::fs::File; use std::io::prelude::*; @@ -1273,6 +1314,9 @@ impl Engine { } } + /// Evaluate a string, but only return errors, if there are any. + /// Useful for when you don't need the result, but still need + /// to keep track of possible errors pub fn consume(&mut self, input: &str) -> Result<(), EvalAltResult> { let mut scope: Scope = Scope::new(); @@ -1281,6 +1325,9 @@ impl Engine { res } + /// Evaluate a string with own scoppe, but only return errors, if there are any. + /// Useful for when you don't need the result, but still need + /// to keep track of possible errors pub fn consume_with_scope(&mut self, scope: &mut Scope, input: &str) -> Result<(), EvalAltResult> { let tokens = lex(input); @@ -1311,6 +1358,8 @@ impl Engine { } } + /// Register the default library. That means, numberic types, char, bool + /// String, arithmetics and string concatenations. pub fn register_default_lib(engine: &mut Engine) { engine.register_type::(); engine.register_type::(); @@ -1388,6 +1437,7 @@ impl Engine { // (*ent).push(FnType::ExternalFn2(Box::new(idx))); } + /// Make a new engine pub fn new() -> Engine { let mut engine = Engine { fns: HashMap::new() }; diff --git a/src/lib.rs b/src/lib.rs index 0b9cc5ca..c3466507 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,4 +1,40 @@ -//! Rhai - embedded scripting for Rust +//! # Rhai - embedded scripting for Rust +//! Rhai is a tiny, simple and very fast embedded scripting language for Rust +//! that gives you a safe and easy way to add scripting to your applications. +//! It provides a familiar syntax based on JS and Rust and a simple Rust interface. +//! Here is a quick example. First, the contents of `my_script.rhai`: +//! +//! ```rust_todo_disable_testing_enable_highlighting +//! fn factorial(x) { +//! if x == 1 { return 1; } +//! x * factorial(x - 1) +//! } +//! +//! compute_something(factorial(10)) +//! ``` +//! +//! And the Rust part: +//! +//! ```rust +//! use rhai::{FnRegister, Engine}; +//! +//! fn compute_something(x: i64) -> bool { +//! (x % 40) == 0 +//! } +//! +//! let mut engine = Engine::new(); +//! engine.register_fn("compute_something", compute_something); +//! # // Very ugly hack incoming, TODO +//! # use std::fs::{File, remove_file}; +//! # use std::io::Write; +//! # use std::mem::drop; +//! # let mut f = File::create("my_script.rhai").unwrap(); +//! # write!(f, "{}", "fn f(x) { if x == 1 { return 1; } x * f(x-1) } compute_something(f(10))"); +//! assert!(engine.eval_file::("my_script.rhai").unwrap()); +//! # let _ = remove_file("my_script.rhai"); +//! ``` +//! +//! [Check out the README on github for more information!](https://github.com/jonathandturner/rhai) // lints required by Rhai #![allow(unknown_lints, @@ -16,3 +52,4 @@ mod tests; pub use engine::{Engine, Scope}; pub use fn_register::FnRegister; +