diff --git a/src/context.rs b/src/context.rs index 928650124..d549f9530 100644 --- a/src/context.rs +++ b/src/context.rs @@ -1,3 +1,5 @@ +use std::rc::Rc; + use serde::Serialize; use serde_json::value::{Value as Json, Map, to_value}; @@ -15,7 +17,7 @@ pub type Object = BTreeMap; /// #[derive(Debug, Clone)] pub struct Context { - data: Json, + data: Rc, } #[inline] @@ -119,13 +121,13 @@ pub fn merge_json(base: &Json, addition: &Object) -> Json { impl Context { /// Create a context with null data pub fn null() -> Context { - Context { data: Json::Null } + Context { data: Rc::new(Json::Null) } } /// Create a context with given data pub fn wraps(e: &T) -> Result { to_value(e).map_err(RenderError::from).map(|d| { - Context { data: d } + Context { data: Rc::new(d) } }) } @@ -144,7 +146,7 @@ impl Context { parse_json_visitor(&mut path_stack, base_path, path_context, relative_path)?; let paths: Vec<&str> = path_stack.iter().map(|x| *x).collect(); - let mut data: &Json = &self.data; + let mut data: &Json = self.data.as_ref(); for p in paths.iter() { if *p == "this" { continue; @@ -162,12 +164,8 @@ impl Context { Ok(data) } - pub fn data(&self) -> &Json { - &self.data - } - - pub fn data_mut(&mut self) -> &mut Json { - &mut self.data + pub fn data_clone(&self) -> Json { + self.data.as_ref().clone() } } diff --git a/src/directives/mod.rs b/src/directives/mod.rs index 4521eeb6b..1090d85a5 100644 --- a/src/directives/mod.rs +++ b/src/directives/mod.rs @@ -22,9 +22,11 @@ pub use self::inline::INLINE_DIRECTIVE; /// -> Result<(), RenderError> { /// // modify json object /// let mut ctx_ref = rc.context_mut(); -/// if let Some(ref mut m) = ctx_ref.data_mut().as_object_mut() { +/// let mut data = ctx_ref.data_clone(); +/// if let Some(ref mut m) = data.as_object_mut() { /// m.insert("hello".to_string(), to_json(&"world".to_owned())); /// } +/// *ctx_ref = Context::wraps(&data)?; /// Ok(()) /// } /// @@ -120,9 +122,13 @@ mod test { -> Result<(), RenderError> { // modify json object let mut ctx_ref = rc.context_mut(); - if let Some(ref mut m) = ctx_ref.data_mut().as_object_mut().as_mut() { + let mut data = ctx_ref.data_clone(); + + if let Some(ref mut m) = data.as_object_mut().as_mut() { m.insert("hello".to_string(), context::to_json(&"war".to_owned())); } + + *ctx_ref = Context::wraps(&data)?; Ok(()) }), );