From 440db952f1b6d2a0bbdb1544ec81570e8ec6528e Mon Sep 17 00:00:00 2001 From: Zhiwei Liang Date: Sat, 26 Sep 2026 02:12:26 -0400 Subject: [PATCH 1/3] Reuse UTF-8 buffers when rendering templates Template files were validated with `str::from_utf8` and then copied into a new `String`, and rendered output was copied back into a `Vec` byte by byte. Use the consuming `String::from_utf8` and `String::into_bytes` conversions so both steps reuse the existing allocation. Binary files and text that fails to parse as a Liquid template still pass through byte-for-byte, since `FromUtf8Error::into_bytes` returns the original buffer and UTF-8 validation never alters it. Signed-off-by: Zhiwei Liang --- crates/templates/src/renderer.rs | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/crates/templates/src/renderer.rs b/crates/templates/src/renderer.rs index e2a9d7f6e6..e2bd08743d 100644 --- a/crates/templates/src/renderer.rs +++ b/crates/templates/src/renderer.rs @@ -89,15 +89,16 @@ impl TemplateContent { raw: Vec, parser: &liquid::Parser, ) -> anyhow::Result { - match string_from_bytes(&raw) { - None => Ok(TemplateContent::Binary(raw)), - Some(s) => { + match String::from_utf8(raw) { + Err(e) => Ok(TemplateContent::Binary(e.into_bytes())), // TODO: try other encodings! + Ok(s) => { match parser.parse(&s) { Ok(t) => Ok(TemplateContent::Template(t)), Err(e) => match understand_liquid_error(e) { TemplateParseFailure::Other(_e) => { // TODO: emit a warning? - Ok(TemplateContent::Binary(raw)) + // `s` owns the original bytes, so the file passes through unchanged + Ok(TemplateContent::Binary(s.into_bytes())) } TemplateParseFailure::UnknownFilter(id) => { Err(anyhow!("internal error in template: unknown filter '{id}'")) @@ -112,22 +113,13 @@ impl TemplateContent { match self { Self::Template(t) => { let text = t.render(globals)?; - Ok(text.bytes().collect()) + Ok(text.into_bytes()) } Self::Binary(v) => Ok(v), } } } -// TODO: this doesn't truly belong in a module that claims to be about -// rendering but the only thing that uses it is the TemplateContent ctor -fn string_from_bytes(bytes: &[u8]) -> Option { - match std::str::from_utf8(bytes) { - Ok(s) => Some(s.to_owned()), - Err(_) => None, // TODO: try other encodings! - } -} - enum TemplateParseFailure { UnknownFilter(String), Other(liquid::Error), From b281511ee60237f1cc8bb5a70e486bbea04d6e01 Mon Sep 17 00:00:00 2001 From: Zhiwei Liang Date: Mon, 28 Sep 2026 00:16:04 -0400 Subject: [PATCH 2/3] Remove unnecessary comment Signed-off-by: Zhiwei Liang --- crates/templates/src/renderer.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/crates/templates/src/renderer.rs b/crates/templates/src/renderer.rs index e2bd08743d..0b6475f050 100644 --- a/crates/templates/src/renderer.rs +++ b/crates/templates/src/renderer.rs @@ -97,7 +97,6 @@ impl TemplateContent { Err(e) => match understand_liquid_error(e) { TemplateParseFailure::Other(_e) => { // TODO: emit a warning? - // `s` owns the original bytes, so the file passes through unchanged Ok(TemplateContent::Binary(s.into_bytes())) } TemplateParseFailure::UnknownFilter(id) => { From 57b22da2bd5a0c6836c9a2ac47b7eab7336b38ad Mon Sep 17 00:00:00 2001 From: Zhiwei Liang Date: Mon, 28 Sep 2026 00:21:23 -0400 Subject: [PATCH 3/3] Explain that FromUtf8Error::into_bytes returns the original bytes Signed-off-by: Zhiwei Liang --- crates/templates/src/renderer.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/templates/src/renderer.rs b/crates/templates/src/renderer.rs index 0b6475f050..e8d3072168 100644 --- a/crates/templates/src/renderer.rs +++ b/crates/templates/src/renderer.rs @@ -90,6 +90,7 @@ impl TemplateContent { parser: &liquid::Parser, ) -> anyhow::Result { match String::from_utf8(raw) { + // `into_bytes` hands back the original bytes that failed UTF-8 validation Err(e) => Ok(TemplateContent::Binary(e.into_bytes())), // TODO: try other encodings! Ok(s) => { match parser.parse(&s) {