Skip to content

Commit

Permalink
Allow declaring named lifetimes.
Browse files Browse the repository at this point in the history
  • Loading branch information
kaj committed Feb 6, 2022
1 parent afa7a50 commit 9b2c730
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 6 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Expand Up @@ -11,7 +11,7 @@ project adheres to

* Breaking change: The generated template functions have a simpler
signature.
* Allow litetimes in template argument types. Issue #106.
* Allow litetimes in template argument types. Issue #106, PR #110.
* Improve error handling in optional warp support, PR #109.
* Current stable rust is 1.57, MSRV is now 1.46.0.
* Update nom dependency to 7.1.0.
Expand Down
9 changes: 9 additions & 0 deletions examples/simple/src/main.rs
Expand Up @@ -329,3 +329,12 @@ fn lifetimes() {
"\n <p>foo</p>\n\n <p>bar</p>\n\n",
);
}

/// [Issue #106](https://github.com/kaj/ructe/issues/106)
#[test]
fn lifetimes2() {
assert_eq!(
r2s(|o| with_lifetime2(o, &["foo", "bar"])),
"\n <p>foo</p>\n\n <p>bar</p>\n\n",
);
}
6 changes: 6 additions & 0 deletions examples/simple/templates/with_lifetime2.rs.html
@@ -0,0 +1,6 @@
@* There can be lifetime annotations in argument types. *@
@<'a>(arg: &[&'a str])

@for x in arg {
<p>@x</p>
}
33 changes: 28 additions & 5 deletions src/template.rs
Expand Up @@ -9,13 +9,14 @@ use nom::bytes::complete::tag;
use nom::character::complete::{char, multispace0};
use nom::combinator::{map, map_res, opt, recognize};
use nom::error::context;
use nom::multi::{many0, many_till, separated_list0};
use nom::multi::{many0, many_till, separated_list0, separated_list1};
use nom::sequence::{delimited, preceded, terminated, tuple};
use std::io::{self, Write};

#[derive(Debug, PartialEq, Eq)]
pub struct Template {
preamble: Vec<String>,
type_args: String,
args: Vec<String>,
body: Vec<TemplateExpression>,
}
Expand All @@ -40,11 +41,14 @@ impl Template {
writeln!(
out,
"\n\
pub fn {name}<W>(_ructe_out_: &mut W{args}) -> io::Result<()> where W: Write {{\n\
pub fn {name}<{ta}{ta_sep}W>(_ructe_out_: &mut W{args}) -> io::Result<()>\n\
where W: Write {{\n\
{body}\
Ok(())\n\
}}",
name = name,
ta = self.type_args,
ta_sep = if self.type_args.is_empty() { "" } else { ", " },
args =
self.args.iter().format_with("", |arg, f| f(&format_args!(
", {}",
Expand All @@ -70,10 +74,28 @@ pub fn template(input: &[u8]) -> PResult<Template> {
),
String::from,
)),
context("expected '@('...')' template declaration.", tag("@")),
opt(delimited(
terminated(tag("<"), multispace0),
context(
"expected type argument or '>'",
map_res(
recognize(separated_list1(
terminated(tag(","), multispace0),
context(
"expected lifetime declaration",
preceded(tag("'"), rust_name),
),
)),
input_to_str,
),
),
tag(">"),
)),
delimited(
context(
"expected '@('...')' template declaration.",
terminated(tag("@("), multispace0),
"expected '('...')' template arguments declaration.",
terminated(tag("("), multispace0),
),
separated_list0(
terminated(tag(","), multispace0),
Expand All @@ -95,8 +117,9 @@ pub fn template(input: &[u8]) -> PResult<Template> {
end_of_file,
),
)),
|((), preamble, args, body)| Template {
|((), preamble, _, type_args, args, body)| Template {
preamble,
type_args: type_args.map(String::from).unwrap_or_default(),
args,
body: body.0,
},
Expand Down

0 comments on commit 9b2c730

Please sign in to comment.