From 364763e039b286774c29c4995df6baba9d22a61a Mon Sep 17 00:00:00 2001 From: WriterV2 Date: Sun, 24 Nov 2024 12:17:32 +0100 Subject: Perf: Avoid unnecessary heap allocations of strings --- src/db/mod.rs | 6 +++--- src/db/product.rs | 2 +- src/db/story.rs | 14 +++++++------- src/handlers/admin.rs | 16 ++++++++-------- src/handlers/frontend_builder.rs | 20 ++++++++++---------- 5 files changed, 29 insertions(+), 29 deletions(-) diff --git a/src/db/mod.rs b/src/db/mod.rs index 51665a3..f1baf44 100644 --- a/src/db/mod.rs +++ b/src/db/mod.rs @@ -19,9 +19,9 @@ pub trait ProductDatabaseHandler { async fn post( &self, pool: &SqlitePool, - name: String, - description: String, - tags: Vec, + name: &str, + description: &str, + tags: Vec<&str>, ) -> Result where Self: Sized; diff --git a/src/db/product.rs b/src/db/product.rs index c21734e..1c8be1f 100644 --- a/src/db/product.rs +++ b/src/db/product.rs @@ -18,7 +18,7 @@ pub struct Product { } impl Product { - pub async fn post(tx: &mut Transaction<'static, Sqlite>, name: String, description: String, tags: Vec) -> Result { + pub async fn post(tx: &mut Transaction<'static, Sqlite>, name: &str, description: &str, tags: Vec<&str>) -> Result { let now = SystemTime::now().duration_since(std::time::UNIX_EPOCH)?.as_millis() as i64; let product = sqlx::query_as!( Product, diff --git a/src/db/story.rs b/src/db/story.rs index 9e5fdb9..5803351 100644 --- a/src/db/story.rs +++ b/src/db/story.rs @@ -76,9 +76,9 @@ impl ProductDatabaseHandler for Story { async fn post( &self, pool: &SqlitePool, - name: String, - description: String, - tags: Vec, + name: &str, + description: &str, + tags: Vec<&str>, ) -> Result where Self: Sized, @@ -114,13 +114,13 @@ impl ProductDatabaseHandler for Story { } } -impl PageBuilder for Story { - fn page_title() -> String { - "Stories".to_string() +impl<'a> PageBuilder<'a> for Story { + fn page_title() -> &'a str { + "Stories" } // TODO: Add pdf and epub icons - fn product_specific_card_content( + fn product_specific_card_content + ProductMarker>( &self, specific_product: &super::product::SpecificProduct, ) -> maud::Markup { diff --git a/src/handlers/admin.rs b/src/handlers/admin.rs index 3d16b32..6cc79c2 100644 --- a/src/handlers/admin.rs +++ b/src/handlers/admin.rs @@ -76,14 +76,13 @@ pub async fn upload_story( } let name = if let Some(name_value) = form.get("name") { - String::from_utf8(name_value.to_vec()).with_context(|| "Failed to parse name")? + std::str::from_utf8(name_value).with_context(|| "Failed to parse name")? } else { return Ok(StatusCode::BAD_REQUEST.into_response()); }; let description = if let Some(description_value) = form.get("description") { - String::from_utf8(description_value.to_vec()) - .with_context(|| "Failed to parse description")? + std::str::from_utf8(description_value).with_context(|| "Failed to parse description")? } else { return Ok(StatusCode::BAD_REQUEST.into_response()); }; @@ -95,7 +94,7 @@ pub async fn upload_story( }; let pdf = if let Some(pdf_value) = form.get("pdf") { - let filename = format_filepath(&name, "pdf"); + let filename = format_filepath(name, "pdf"); let file = std::fs::File::create_new(filename)?; BufWriter::new(file).write_all(pdf_value)?; pdf_value.to_vec() @@ -104,7 +103,7 @@ pub async fn upload_story( }; let epub = if let Some(epub_value) = form.get("epub") { - let filename = format_filepath(&name, "epub"); + let filename = format_filepath(name, "epub"); let file = std::fs::File::create_new(filename)?; BufWriter::new(file).write_all(epub_value)?; epub_value.to_vec() @@ -112,10 +111,11 @@ pub async fn upload_story( return Ok(StatusCode::BAD_REQUEST.into_response()); }; - let mut tags: Vec = Vec::new(); + let mut tags: Vec<&str> = Vec::new(); if let Some(tags_value) = form.get("tag") { - for tag in String::from_utf8(tags_value.to_vec())?.split(",") { - tags.push(tag.trim().to_string()); + let tagstring = std::str::from_utf8(tags_value)?; + for tag in tagstring.split(",") { + tags.push(tag.trim()); } } diff --git a/src/handlers/frontend_builder.rs b/src/handlers/frontend_builder.rs index 515277e..dd49854 100644 --- a/src/handlers/frontend_builder.rs +++ b/src/handlers/frontend_builder.rs @@ -8,10 +8,10 @@ use crate::db::ProductDatabaseHandler; use crate::error::AppError; pub async fn home() -> Result { - Ok(html!((page("Home".to_string(), Markup::default())))) + Ok(html!((page("Home", Markup::default())))) } -fn page(page_title: String, content: Markup) -> Markup { +fn page(page_title: &str, content: Markup) -> Markup { html!( (head(page_title)) body class="bg-[#eae3d2] text-[#333] dark:bg-[#333] dark:text-[#eae3d2] font-mono text-base" { @@ -41,9 +41,9 @@ fn navbar() -> Markup { }) } -fn cards( +fn cards<'a, T: PageBuilder<'a> + ProductMarker>( products: Vec>, - category: String, + category: &str, ) -> Markup { html!( div class="m-12" { @@ -57,7 +57,7 @@ fn cards( ) } -fn card(specific_product: SpecificProduct) -> Markup { +fn card<'a, T: PageBuilder<'a> + ProductMarker>(specific_product: SpecificProduct) -> Markup { let date = |i: i64| -> String { if let Some(datetime) = DateTime::from_timestamp(i / 1_000, 0) { return format!("{}", datetime.format("%Y/%m/%d")).to_string(); @@ -87,7 +87,7 @@ fn card(specific_product: SpecificProduct) -> ) } -fn head(page_title: String) -> Markup { +fn head(page_title: &str) -> Markup { html! { head { (DOCTYPE) @@ -98,7 +98,7 @@ fn head(page_title: String) -> Markup { } } -pub async fn build_page( +pub async fn build_page<'a, T: Sized + ProductMarker + PageBuilder<'a> + ProductDatabaseHandler>( ctx: Extension, ) -> Result { Ok(html!( @@ -112,9 +112,9 @@ pub async fn build_page String; - fn product_specific_card_content( +pub trait PageBuilder<'a> { + fn page_title() -> &'a str; + fn product_specific_card_content + ProductMarker>( &self, specific_product: &SpecificProduct, ) -> Markup; -- cgit v1.2.3