Skip to content

Commit

Permalink
Implement enum variants
Browse files Browse the repository at this point in the history
  • Loading branch information
Kijewski committed Nov 24, 2024
1 parent e4b8979 commit b9f1a5f
Show file tree
Hide file tree
Showing 10 changed files with 619 additions and 89 deletions.
12 changes: 12 additions & 0 deletions rinja/src/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -254,3 +254,15 @@ impl<L: FastWritable, R: FastWritable> FastWritable for Concat<L, R> {
self.1.write_into(dest)
}
}

pub trait EnumVariantTemplate {
fn render_into<W: fmt::Write + ?Sized>(&self, writer: &mut W) -> crate::Result<()>;

#[inline]
fn size_hint(&self) -> usize {
Self::SIZE_HINT
}

const SIZE_HINT: usize;
const MIME_TYPE: &'static str;
}
15 changes: 11 additions & 4 deletions rinja/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ pub use crate::helpers::PrimitiveType;
/// `.render()`.
///
/// [dynamic methods calls]: <https://doc.rust-lang.org/stable/std/keyword.dyn.html>
pub trait Template: fmt::Display {
pub trait Template: fmt::Display + filters::FastWritable {
/// Helper method which allocates a new `String` and renders into it
fn render(&self) -> Result<String> {
let mut buf = String::new();
Expand Down Expand Up @@ -152,17 +152,17 @@ pub trait Template: fmt::Display {
impl<T: Template + ?Sized> Template for &T {
#[inline]
fn render_into<W: fmt::Write + ?Sized>(&self, writer: &mut W) -> Result<()> {
T::render_into(self, writer)
<T as Template>::render_into(self, writer)
}

#[inline]
fn render(&self) -> Result<String> {
T::render(self)
<T as Template>::render(self)
}

#[inline]
fn write_into<W: io::Write + ?Sized>(&self, writer: &mut W) -> io::Result<()> {
T::write_into(self, writer)
<T as Template>::write_into(self, writer)
}

const SIZE_HINT: usize = T::SIZE_HINT;
Expand Down Expand Up @@ -264,6 +264,13 @@ mod tests {
const MIME_TYPE: &'static str = "text/plain; charset=utf-8";
}

impl filters::FastWritable for Test {
#[inline]
fn write_into<W: fmt::Write + ?Sized>(&self, f: &mut W) -> crate::Result<()> {
self.render_into(f)
}
}

impl fmt::Display for Test {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
Expand Down
2 changes: 1 addition & 1 deletion rinja_derive/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ mime_guess = "2"
proc-macro2 = "1"
quote = "1"
rustc-hash = "2.0.0"
syn = "2.0.3"
syn = { version = "2.0.3", features = ["full"] }

[dev-dependencies]
console = "0.15.8"
Expand Down
2 changes: 1 addition & 1 deletion rinja_derive/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,7 @@ impl RawConfig<'_> {
}
}

#[cfg_attr(feature = "config", derive(Deserialize))]
#[cfg_attr(feature = "config", derive(serde::Deserialize))]
struct General<'a> {
#[cfg_attr(feature = "config", serde(borrow))]
dirs: Option<Vec<&'a str>>,
Expand Down
64 changes: 31 additions & 33 deletions rinja_derive/src/generator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,22 +22,12 @@ use crate::integration::{Buffer, impl_everything, write_header};
use crate::{BUILT_IN_FILTERS, CRATE, CompileError, FileInfo, MsgValidEscapers};

pub(crate) fn template_to_string(
buf: &mut Buffer,
input: &TemplateInput<'_>,
contexts: &HashMap<&Arc<Path>, Context<'_>, FxBuildHasher>,
heritage: Option<&Heritage<'_, '_>>,
) -> Result<String, CompileError> {
let mut buf = Buffer::new();
template_into_buffer(input, contexts, heritage, &mut buf, false)?;
Ok(buf.into_string())
}

pub(crate) fn template_into_buffer(
input: &TemplateInput<'_>,
contexts: &HashMap<&Arc<Path>, Context<'_>, FxBuildHasher>,
heritage: Option<&Heritage<'_, '_>>,
buf: &mut Buffer,
only_template: bool,
) -> Result<(), CompileError> {
target: Option<&str>,
) -> Result<usize, CompileError> {
let ctx = &contexts[&input.path];
let generator = Generator::new(
input,
Expand All @@ -47,7 +37,7 @@ pub(crate) fn template_into_buffer(
input.block.is_some(),
0,
);
let mut result = generator.build(ctx, buf, only_template);
let mut result = generator.build(ctx, buf, target);
if let Err(err) = &mut result {
if err.span.is_none() {
err.span = input.source_span;
Expand Down Expand Up @@ -110,24 +100,22 @@ impl<'a, 'h> Generator<'a, 'h> {
mut self,
ctx: &Context<'a>,
buf: &mut Buffer,
only_template: bool,
) -> Result<(), CompileError> {
if !only_template {
target: Option<&str>,
) -> Result<usize, CompileError> {
if target.is_none() {
buf.write(format_args!(
"\
const _: () = {{\
extern crate {CRATE} as rinja;\
"
));
}

self.impl_template(ctx, buf)?;
impl_everything(self.input.ast, buf, only_template);

if !only_template {
let size_hint = self.impl_template(ctx, buf, target.unwrap_or("rinja::Template"))?;
if target.is_none() {
impl_everything(self.input.ast, buf);
buf.write("};");
}
Ok(())
Ok(size_hint)
}

fn push_locals<T, F>(&mut self, callback: F) -> Result<T, CompileError>
Expand Down Expand Up @@ -178,8 +166,9 @@ impl<'a, 'h> Generator<'a, 'h> {
&mut self,
ctx: &Context<'a>,
buf: &mut Buffer,
target: &str,
) -> Result<usize, CompileError> {
write_header(self.input.ast, buf, "rinja::Template", None);
write_header(self.input.ast, buf, target, None);
buf.write(
"fn render_into<RinjaW>(&self, writer: &mut RinjaW) -> rinja::Result<()>\
where \
Expand All @@ -189,7 +178,6 @@ impl<'a, 'h> Generator<'a, 'h> {
use rinja::helpers::core::fmt::Write as _;",
);

buf.set_discard(self.buf_writable.discard);
// Make sure the compiler understands that the generated code depends on the template files.
let mut paths = self
.contexts
Expand All @@ -212,14 +200,7 @@ impl<'a, 'h> Generator<'a, 'h> {
}
}

let size_hint = if let Some(heritage) = self.heritage {
self.handle(heritage.root, heritage.root.nodes, buf, AstLevel::Top)
} else {
self.handle(ctx, ctx.nodes, buf, AstLevel::Top)
}?;
buf.set_discard(false);

self.flush_ws(Ws(None, None));
let size_hint = self.impl_template_inner(ctx, buf)?;

buf.write(format_args!(
"\
Expand All @@ -231,6 +212,23 @@ impl<'a, 'h> Generator<'a, 'h> {
));

buf.write('}');

Ok(size_hint)
}

fn impl_template_inner(
&mut self,
ctx: &Context<'a>,
buf: &mut Buffer,
) -> Result<usize, CompileError> {
buf.set_discard(self.buf_writable.discard);
let size_hint = if let Some(heritage) = self.heritage {
self.handle(heritage.root, heritage.root.nodes, buf, AstLevel::Top)
} else {
self.handle(ctx, ctx.nodes, buf, AstLevel::Top)
}?;
self.flush_ws(Ws(None, None));
buf.set_discard(false);
Ok(size_hint)
}

Expand Down
Loading

0 comments on commit b9f1a5f

Please sign in to comment.