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]]
name = "blueprint"
version = "0.1.0"
version = "0.2.0"
dependencies = [
"nom",
"structopt",

View File

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

View File

@ -40,6 +40,7 @@ pub enum Expr<'a> {
},
Variable(Cow<'a, str>),
Str(Cow<'a, str>),
}
use crate::env::{Env, Value};
@ -105,6 +106,7 @@ impl Expr<'_> {
pub fn eval<'a>(&self, env: &'a Env) -> Cow<'a, Value> {
match self {
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 } => {
let val1 = expr1.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]
fn test_parse_eq() {
let input = "one {% if foo == bar %} two {% end %} three";

View File

@ -1,11 +1,11 @@
use crate::ast::*;
use nom::{
branch::alt,
bytes::complete::{tag, take_until},
bytes::complete::{is_not, tag, take_until},
character::complete::{alpha1, multispace0, multispace1},
combinator::{map, opt},
multi::many0,
sequence::tuple,
sequence::{delimited, tuple},
IResult,
};
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)
}
/// 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> {
expr_var(i)
alt((expr_str, expr_var))(i)
}
fn cmp_op(i: &str) -> IResult<&str, CmpOp> {