From cc79f59a7d6a88fd24a810972e5706ba395fa759 Mon Sep 17 00:00:00 2001 From: Austin Schaefer Date: Thu, 3 Sep 2026 21:26:56 +0200 Subject: [PATCH] Decode list_ranked_articles rows via a From impl Replaces the inline .map() closure with From for RankedArticleRow, separating "what a raw SQLite row looks like" from the query itself. --- crates/db/src/articles.rs | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/crates/db/src/articles.rs b/crates/db/src/articles.rs index e91d143..2b4f4ea 100644 --- a/crates/db/src/articles.rs +++ b/crates/db/src/articles.rs @@ -108,7 +108,6 @@ impl Db { if let Some(feed_id) = feed_id { query = query.filter(dsl::feed_id.eq(feed_id.to_string())); } - type Row = (String, String, String, String, String, String, Option); let rows: Vec = query .order(dsl::final_score.desc()) .limit(limit) @@ -123,20 +122,25 @@ impl Db { )) .load(&mut conn) .await?; - Ok(rows - .into_iter() - .map( - |(id, feed_id, title, url, summary, topics_json, final_score)| RankedArticleRow { - id, - feed_id, - title, - url, - summary, - topics: serde_json::from_str(&topics_json).unwrap_or_default(), - final_score, - }, - ) - .collect()) + Ok(rows.into_iter().map(RankedArticleRow::from).collect()) + } +} + +/// Raw shape of one `list_ranked_articles` row as loaded from SQLite — +/// `topics` is still the JSON string column, not yet decoded. +type Row = (String, String, String, String, String, String, Option); + +impl From for RankedArticleRow { + fn from((id, feed_id, title, url, summary, topics_json, final_score): Row) -> Self { + Self { + id, + feed_id, + title, + url, + summary, + topics: serde_json::from_str(&topics_json).unwrap_or_default(), + final_score, + } } }