Add string literals

This commit is contained in:
2021-05-20 03:41:01 +02:00
parent a63956d13c
commit 2d0875188e
5 changed files with 43 additions and 5 deletions

2
Cargo.lock generated
View File

@ -46,7 +46,7 @@ dependencies = [
[[package]] [[package]]
name = "blueprint" name = "blueprint"
version = "0.1.0" version = "0.2.0"
dependencies = [ dependencies = [
"nom", "nom",
"structopt", "structopt",

View File

@ -1,6 +1,6 @@
[package] [package]
name = "blueprint" name = "blueprint"
version = "0.1.0" version = "0.2.0"
authors = ["Joakim Hulthe <joakim@hulthe.net>"] authors = ["Joakim Hulthe <joakim@hulthe.net>"]
description = "A simple templating library" description = "A simple templating library"
edition = "2018" edition = "2018"

View File

@ -40,6 +40,7 @@ pub enum Expr<'a> {
}, },
Variable(Cow<'a, str>), Variable(Cow<'a, str>),
Str(Cow<'a, str>),
} }
use crate::env::{Env, Value}; use crate::env::{Env, Value};
@ -105,6 +106,7 @@ impl Expr<'_> {
pub fn eval<'a>(&self, env: &'a Env) -> Cow<'a, Value> { pub fn eval<'a>(&self, env: &'a Env) -> Cow<'a, Value> {
match self { match self {
Expr::Variable(var) => Cow::Borrowed(env.get(&**var).unwrap_or(&Value::Null)), Expr::Variable(var) => Cow::Borrowed(env.get(&**var).unwrap_or(&Value::Null)),
Expr::Str(s) => Cow::Owned(Value::Str(s.to_string())),
Expr::Cmp { op, expr1, expr2 } => { Expr::Cmp { op, expr1, expr2 } => {
let val1 = expr1.eval(env); let val1 = expr1.eval(env);
let val2 = expr2.eval(env); let val2 = expr2.eval(env);

View File

@ -55,6 +55,34 @@ mod test {
); );
} }
#[test]
fn test_parse_if_str() {
let input = "one {% if foo >= \"bar\" %} two {% end %} three";
let ast = parse_file(&input).expect("failed to parse");
eprintln!("{:#?}", ast);
assert_eq!(
ast,
Template {
parts: vec![
Part::Text("one ".into()),
Part::If {
if_then: IfThen {
cond: Expr::Cmp {
op: CmpOp::GrEq,
expr1: Box::new(Expr::Variable("foo".into())),
expr2: Box::new(Expr::Str("bar".into())),
},
parts: vec![Part::Text(" two ".into()),]
},
elifs: vec![],
else_part: None,
},
Part::Text(" three".into()),
],
}
);
}
#[test] #[test]
fn test_parse_eq() { fn test_parse_eq() {
let input = "one {% if foo == bar %} two {% end %} three"; let input = "one {% if foo == bar %} two {% end %} three";

View File

@ -1,11 +1,11 @@
use crate::ast::*; use crate::ast::*;
use nom::{ use nom::{
branch::alt, branch::alt,
bytes::complete::{tag, take_until}, bytes::complete::{is_not, tag, take_until},
character::complete::{alpha1, multispace0, multispace1}, character::complete::{alpha1, multispace0, multispace1},
combinator::{map, opt}, combinator::{map, opt},
multi::many0, multi::many0,
sequence::tuple, sequence::{delimited, tuple},
IResult, IResult,
}; };
use std::borrow::Cow; use std::borrow::Cow;
@ -17,8 +17,16 @@ fn expr_var(i: &str) -> IResult<&str, Expr> {
map(alpha1, |v| Expr::Variable(Cow::Borrowed(v)))(i) map(alpha1, |v| Expr::Variable(Cow::Borrowed(v)))(i)
} }
/// Try to parse an Expr::Str
fn expr_str(i: &str) -> IResult<&str, Expr> {
const QUOTE: &str = "\"";
map(delimited(tag(QUOTE), is_not(QUOTE), tag(QUOTE)), |s| {
Expr::Str(Cow::Borrowed(s))
})(i)
}
fn expr1(i: &str) -> IResult<&str, Expr> { fn expr1(i: &str) -> IResult<&str, Expr> {
expr_var(i) alt((expr_str, expr_var))(i)
} }
fn cmp_op(i: &str) -> IResult<&str, CmpOp> { fn cmp_op(i: &str) -> IResult<&str, CmpOp> {