From 5cfef325b03b25ad96d6c229a5ec3fd6a32f700d Mon Sep 17 00:00:00 2001 From: Dirkjan Ochtman Date: Wed, 15 Dec 2021 14:08:45 +0100 Subject: Use a separate trait for object safety (#579) This is relatively major change to the main trait's API. For context, I always started from the concept of monomorphized traits, but later several contributors asked about object safety. At that point I made `Template` object-safe, and then even later added a `SizedTemplate` to make some things easier for people who don't need object safety. However, having object-safety in the primary trait is bad for performance (a substantial number of calls into the virtual `Write` trait is relatively slow), and I don't think those who don't need object safety should pay for the cost of having it. Additionally, I feel using associated consts for the extension and size hint is more idiomatic than having accessor methods. I don't know why I didn't use these from the start -- maybe associated consts didn't exist yet, or I didn't yet know how/when to use them. Askama is pretty old at this point... --- askama_shared/src/generator.rs | 22 +++++----------------- 1 file changed, 5 insertions(+), 17 deletions(-) (limited to 'askama_shared/src') diff --git a/askama_shared/src/generator.rs b/askama_shared/src/generator.rs index 41b81df..56c82aa 100644 --- a/askama_shared/src/generator.rs +++ b/askama_shared/src/generator.rs @@ -128,7 +128,7 @@ impl<'a, S: std::hash::BuildHasher> Generator<'a, S> { ) -> Result<(), CompileError> { self.write_header(buf, "::askama::Template", None)?; buf.writeln( - "fn render_into(&self, writer: &mut dyn ::std::fmt::Write) -> \ + "fn render_into(&self, writer: &mut (impl ::std::fmt::Write + ?Sized)) -> \ ::askama::Result<()> {", )?; @@ -160,25 +160,13 @@ impl<'a, S: std::hash::BuildHasher> Generator<'a, S> { buf.writeln("Ok(())")?; buf.writeln("}")?; - buf.writeln("fn extension(&self) -> Option<&'static str> {")?; + buf.writeln("const EXTENSION: ::std::option::Option<&'static ::std::primitive::str> = ")?; buf.writeln(&format!("{:?}", self.input.extension()))?; - buf.writeln("}")?; + buf.writeln(";")?; - buf.writeln("fn size_hint(&self) -> usize {")?; + buf.writeln("const SIZE_HINT: ::std::primitive::usize = ")?; buf.writeln(&format!("{}", size_hint))?; - buf.writeln("}")?; - - buf.writeln("}")?; - - self.write_header(buf, "::askama::SizedTemplate", None)?; - - buf.writeln("fn size_hint() -> usize {")?; - buf.writeln(&format!("{}", size_hint))?; - buf.writeln("}")?; - - buf.writeln("fn extension() -> Option<&'static str> {")?; - buf.writeln(&format!("{:?}", self.input.extension()))?; - buf.writeln("}")?; + buf.writeln(";")?; buf.writeln("}")?; Ok(()) -- cgit