Skip to content

Commit

Permalink
initial $ support / add range for array
Browse files Browse the repository at this point in the history
  • Loading branch information
fiji-flo committed Dec 27, 2017
1 parent c8dc90f commit d8c681d
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 9 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "gtmpl"
version = "0.3.1"
version = "0.3.2"
authors = ["Florian Merz <flomerz@gmail.com>"]
description = "The Golang Templating Language for Rust"
license = "MIT"
Expand Down
41 changes: 33 additions & 8 deletions src/exec.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::any::Any;
use std::sync::Arc;
use std::io::Write;
use std::collections::{HashMap, VecDeque};
use std::collections::VecDeque;

use template::Template;
use utils::is_true;
Expand Down Expand Up @@ -396,7 +396,7 @@ impl<'a, 'b, T: Write> State<'a, 'b, T> {

fn one_iteration(
&mut self,
key: String,
key: Value,
val: Arc<Any>,
range: &'a RangeNode,
) -> Result<(), String> {
Expand All @@ -416,15 +416,13 @@ impl<'a, 'b, T: Write> State<'a, 'b, T> {

fn walk_range(&mut self, ctx: &Context, range: &'a RangeNode) -> Result<(), String> {
let val = self.eval_pipeline(ctx, &range.pipe)?;
if let Some(map) = val.downcast_ref::<HashMap<String, Arc<Any>>>() {
for (k, v) in map {
self.one_iteration(k.clone(), Arc::clone(v), range)?;
}
}
if let Some(value) = val.downcast_ref::<Value>() {
match *value {
Value::Object(ref map) | Value::Map(ref map) => for (k, v) in map.clone() {
self.one_iteration(k.clone(), Arc::new(v), range)?;
self.one_iteration(Value::from(k), Arc::new(v), range)?;
},
Value::Array(ref vec) => for (k, v) in vec.iter().enumerate() {
self.one_iteration(Value::from(k), Arc::new(v.clone()), range)?;
},
_ => return Err(format!("invalid range: {:?}", value)),
}
Expand Down Expand Up @@ -470,6 +468,7 @@ fn not_a_function(args: &[Nodes], val: &Option<Arc<Any>>) -> Result<(), String>
#[cfg(test)]
mod tests_mocked {
use super::*;
use std::collections::HashMap;

#[test]
fn simple_template() {
Expand Down Expand Up @@ -582,6 +581,22 @@ mod tests_mocked {
assert_eq!(String::from_utf8(w).unwrap(), Value::NoValue.to_string());
}

#[test]
fn test_dollar_dot() {
#[derive(Gtmpl, Clone)]
struct Foo {
foo: u8,
}
let data = Context::from(Foo { foo: 1u8 }).unwrap();
let mut w: Vec<u8> = vec![];
let mut t = Template::default();
println!("{:?}", t.parse(r#"{{$.foo}}"#));
assert!(t.parse(r#"{{$.foo}}"#).is_ok());
let out = t.execute(&mut w, &data);
assert!(out.is_ok());
assert_eq!(String::from_utf8(w).unwrap(), "1");
}

#[test]
fn test_dot_value() {
#[derive(Gtmpl, Clone)]
Expand Down Expand Up @@ -682,6 +697,16 @@ mod tests_mocked {
let out = t.execute(&mut w, &data);
assert!(out.is_ok());
assert_eq!(to_sorted_string(w), "12");

let vec = vec!["foo", "bar", "2000"];
let data = Context::from(vec).unwrap();
let mut w: Vec<u8> = vec![];
let mut t = Template::default();
assert!(t.parse(r#"{{ range . -}} {{.}} {{- end }}"#).is_ok());
let out = t.execute(&mut w, &data);
println!("{:?}", out);
assert!(out.is_ok());
assert_eq!(String::from_utf8(w).unwrap(), "foobar2000");
}

#[test]
Expand Down
3 changes: 3 additions & 0 deletions src/parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -713,6 +713,9 @@ impl<'a> Parser<'a> {
}

fn use_var(&self, tree_id: TreeId, pos: Pos, name: &str) -> Result<VariableNode, String> {
if name == "$" {
return Ok(VariableNode::new(tree_id, pos, name));
}
self.tree
.as_ref()
.and_then(|t| {
Expand Down

0 comments on commit d8c681d

Please sign in to comment.