djc / askama

Type-safe, compiled Jinja-like templates for Rust

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Remove the need to import askama itself when using integration crates

nc7s opened this issue · comments

While wording on #961, I wandered off to find the cause for the need as the title goes. A rough scan reveals that askama_derive generates some uses of ::askama::, for example, this:

self.write_header(buf, "::askama::Template", None)?;
buf.writeln(
"fn render_into(&self, writer: &mut (impl ::std::fmt::Write + ?Sized)) -> \
::askama::Result<()> {",

… which leads to the need, as sub-dependencies can't be used directly. If they are removed, probably we can depend solely on integration crates?

A possible way to do this might be something like

#[inline]
fn _askama(tail: &str) -> String {
	format!("::{}::askama{tail}",
		#[cfg(feature = "with-actix-web")]
		"askama_actix",
		#[cfg(feature = "with-axum")]
		"askama_axum",
		// ...
	)
}

buf.write("fn render_into(&self, writer: &mut (impl ::std::fmt::Write + ?Sized)) -> ")?;
buf.writeln(&_askama("::Result<()> {"))?;

… which isn't pretty, but works.

Well, I wouldn't want to do this in a way that requires adding another intermediate allocation, but perhaps a newtype with a Display implementation could do the job. I'd be open to reviewing such a PR.

How about checking for existence of ::askama::, and if so, splitting the &str into head, prefix and tail, then 1) push head, 2) push #[cfg] activated prefix, 3) push tail?

This would be a waste of branching in most cases, so probably a separate fn writeln_askama or something.

Happy to review a PR that is mindful of the performance impact.