make engine clone-able

This commit is contained in:
Lukáš Hozda 2017-12-31 19:58:50 +01:00
parent f8606aec4c
commit ccc16f42f9

View File

@ -4,6 +4,7 @@ use std::cmp::{PartialEq, PartialOrd};
use std::collections::HashMap; use std::collections::HashMap;
use std::error::Error; use std::error::Error;
use std::fmt; use std::fmt;
use std::sync::Arc;
use std::ops::{Add, BitAnd, BitOr, BitXor, Deref, Div, Mul, Neg, Rem, Shl, Shr, Sub}; use std::ops::{Add, BitAnd, BitOr, BitXor, Deref, Div, Mul, Neg, Rem, Shl, Shr, Sub};
use any::{Any, AnyExt}; use any::{Any, AnyExt};
@ -108,9 +109,10 @@ pub struct FnSpec {
/// } /// }
/// } /// }
/// ``` /// ```
#[derive(Clone)]
pub struct Engine { pub struct Engine {
/// A hashmap containing all functions know to the engine /// A hashmap containing all functions known to the engine
pub fns: HashMap<FnSpec, FnIntExt>, pub fns: HashMap<FnSpec, Arc<FnIntExt>>,
} }
pub enum FnIntExt { pub enum FnIntExt {
@ -174,7 +176,7 @@ impl Engine {
.get(&spec) .get(&spec)
.or_else(|| self.fns.get(&spec1)) .or_else(|| self.fns.get(&spec1))
.ok_or(EvalAltResult::ErrorFunctionNotFound) .ok_or(EvalAltResult::ErrorFunctionNotFound)
.and_then(move |f| match *f { .and_then(move |f| match **f {
FnIntExt::Ext(ref f) => f(args), FnIntExt::Ext(ref f) => f(args),
FnIntExt::Int(ref f) => { FnIntExt::Int(ref f) => {
let mut scope = Scope::new(); let mut scope = Scope::new();
@ -198,7 +200,7 @@ impl Engine {
let spec = FnSpec { ident, args }; let spec = FnSpec { ident, args };
self.fns.insert(spec, FnIntExt::Ext(f)); self.fns.insert(spec, Arc::new(FnIntExt::Ext(f)));
} }
/// Register a type for use with Engine. Keep in mind that /// Register a type for use with Engine. Keep in mind that
@ -639,7 +641,7 @@ impl Engine {
args: None, args: None,
}; };
self.fns.insert(spec, FnIntExt::Int(local_f)); self.fns.insert(spec, Arc::new(FnIntExt::Int(local_f)));
} }
for o in os { for o in os {
@ -688,7 +690,7 @@ impl Engine {
/// Useful for when you don't need the result, but still need /// Useful for when you don't need the result, but still need
/// to keep track of possible errors /// to keep track of possible errors
pub fn consume(&mut self, input: &str) -> Result<(), EvalAltResult> { pub fn consume(&mut self, input: &str) -> Result<(), EvalAltResult> {
self.consume_with_scope(&mut Scope::new(), input) self.consume_with_scope(&mut Scope::new(), input)
} }
/// Evaluate a string with own scoppe, but only return errors, if there are any. /// Evaluate a string with own scoppe, but only return errors, if there are any.
@ -718,7 +720,7 @@ impl Engine {
args: None, args: None,
}; };
self.fns.insert(spec, FnIntExt::Int(local_f)); self.fns.insert(spec, Arc::new(FnIntExt::Int(local_f)));
} }
for o in os { for o in os {