Skip to content

Commit

Permalink
fix: Isolate context creation
Browse files Browse the repository at this point in the history
If nothing else, this makes me feel better about who has acess to do
what.

BREAKING CHANGE: How to create a `Context` has changed.
  • Loading branch information
epage committed Sep 13, 2018
1 parent 3f8e943 commit 00cac8c
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 21 deletions.
51 changes: 37 additions & 14 deletions src/interpreter/context.rs
Expand Up @@ -94,16 +94,18 @@ pub struct Stack {
}

impl Stack {
pub fn new() -> Self {
pub fn empty() -> Self {
Self {
globals: Object::new(),
// Mutable frame for globals.
stack: vec![Object::new()],
}
}

pub fn with_globals(&mut self, values: Object) {
self.globals = values;
pub fn with_globals(globals: Object) -> Self {
let mut stack = Self::empty();
stack.globals = globals;
stack
}

/// Creates a new variable scope chained to a parent scope.
Expand Down Expand Up @@ -197,36 +199,57 @@ impl Stack {

impl Default for Stack {
fn default() -> Self {
Self::new()
Self::empty()
}
}

#[derive(Default)]
pub struct Context {
stack: Stack,

interrupt: InterruptState,
cycles: CycleStateInner,

pub struct ContextBuilder {
globals: Object,
filters: sync::Arc<HashMap<&'static str, BoxedValueFilter>>,
}

impl Context {
impl ContextBuilder {
/// Creates a new, empty rendering context.
pub fn new() -> Self {
Default::default()
}

pub fn with_values(mut self, values: Object) -> Self {
self.stack.with_globals(values);
pub fn set_globals(mut self, values: Object) -> Self {
self.globals = values;
self
}

pub fn with_filters(mut self, filters: &sync::Arc<HashMap<&'static str, BoxedValueFilter>>) -> Self {
pub fn set_filters(mut self, filters: &sync::Arc<HashMap<&'static str, BoxedValueFilter>>) -> Self {
self.filters = sync::Arc::clone(filters);
self
}

pub fn build(self) -> Context {
Context {
stack: Stack::with_globals(self.globals),
interrupt: InterruptState::default(),
cycles: CycleStateInner::default(),
filters: self.filters,
}
}
}

#[derive(Default)]
pub struct Context {
stack: Stack,

interrupt: InterruptState,
cycles: CycleStateInner,

filters: sync::Arc<HashMap<&'static str, BoxedValueFilter>>,
}

impl Context {
pub fn new() -> Self {
Context::default()
}

pub fn get_filter<'b>(&'b self, name: &str) -> Option<&'b FilterValue> {
self.filters.get(name).map(|f| {
let f: &FilterValue = f;
Expand Down
2 changes: 1 addition & 1 deletion src/interpreter/mod.rs
Expand Up @@ -8,7 +8,7 @@ mod text;
mod variable;

pub use self::argument::Argument;
pub use self::context::{unexpected_value_error, Context, Interrupt, InterruptState};
pub use self::context::{unexpected_value_error, ContextBuilder, Context, Interrupt, InterruptState};
pub use self::filter::{BoxedValueFilter, FilterError, FilterResult, FilterValue, FnFilterValue};
pub use self::output::{FilterPrototype, Output};
pub use self::renderable::Renderable;
Expand Down
3 changes: 2 additions & 1 deletion src/tags/for_block.rs
Expand Up @@ -299,6 +299,7 @@ mod test {
use std::collections::HashMap;
use std::sync;

use interpreter::ContextBuilder;
use compiler;
use interpreter;

Expand Down Expand Up @@ -636,7 +637,7 @@ mod test {
as interpreter::FnFilterValue)
.into(),
);
let mut context = Context::new().with_filters(&sync::Arc::new(filters));
let mut context = ContextBuilder::new().set_filters(&sync::Arc::new(filters)).build();

context.stack_mut().set_global_val(
"array",
Expand Down
5 changes: 3 additions & 2 deletions src/tags/include_tag.rs
Expand Up @@ -65,6 +65,7 @@ mod test {
use value;
use compiler;
use filters;
use interpreter::ContextBuilder;
use interpreter;

use super::*;
Expand Down Expand Up @@ -97,7 +98,7 @@ mod test {

let mut filters: HashMap<&'static str, interpreter::BoxedValueFilter> = HashMap::new();
filters.insert("size",(filters::size as interpreter::FnFilterValue).into());
let mut context = Context::new().with_filters(&sync::Arc::new(filters));
let mut context = ContextBuilder::new().set_filters(&sync::Arc::new(filters)).build();
context.stack_mut().set_global_val("num", value::Value::scalar(5f64));
context.stack_mut().set_global_val("numTwo", value::Value::scalar(10f64));
let output = template.render(&mut context).unwrap();
Expand All @@ -114,7 +115,7 @@ mod test {

let mut filters: HashMap<&'static str, interpreter::BoxedValueFilter> = HashMap::new();
filters.insert("size",(filters::size as interpreter::FnFilterValue).into());
let mut context = Context::new().with_filters(&sync::Arc::new(filters));
let mut context = ContextBuilder::new().set_filters(&sync::Arc::new(filters)).build();
context.stack_mut().set_global_val("num", value::Value::scalar(5f64));
context.stack_mut().set_global_val("numTwo", value::Value::scalar(10f64));
let output = template.render(&mut context).unwrap();
Expand Down
7 changes: 4 additions & 3 deletions src/template.rs
Expand Up @@ -23,9 +23,10 @@ impl Template {

/// Renders an instance of the Template, using the given globals.
pub fn render_to(&self, writer: &mut Write, globals: &Object) -> Result<()> {
let mut data = interpreter::Context::new()
.with_filters(&self.filters)
.with_values(globals.clone());
let mut data = interpreter::ContextBuilder::new()
.set_filters(&self.filters)
.set_globals(globals.clone())
.build();
self.template
.render_to(writer, &mut data)
}
Expand Down

0 comments on commit 00cac8c

Please sign in to comment.