web: Extract shared feed assembly into a FeedData DTO #104

Merged
rosa merged 4 commits from refactor/shared-feed-assembly into main 2026-07-05 00:35:51 +00:00
Owner

The RSS and Atom feed handlers duplicated their profile resolution, per-post permalink construction, blog URL building, and content-type plumbing, with only the format-specific builders differing. That duplication had already produced drift (see #94).

Changes

  • Introduce a format-agnostic FeedData / FeedEntry DTO with a FeedData::from_profile constructor that resolves per-post permalinks, the blog URL, and the blog title/description once.
  • Rewrite get_user_rss and get_user_atom to resolve the profile, build a FeedData, and map it into their own crate's builders. A field belonging to an entry or the feed now has one home.
  • Fold the content-type header handling into a shared feed_response helper.

Output is unchanged — this is a pure restructuring. format, clippy, and ci all pass.

Closes #101.

The RSS and Atom feed handlers duplicated their profile resolution, per-post permalink construction, blog URL building, and content-type plumbing, with only the format-specific builders differing. That duplication had already produced drift (see #94). ## Changes - Introduce a format-agnostic `FeedData` / `FeedEntry` DTO with a `FeedData::from_profile` constructor that resolves per-post permalinks, the blog URL, and the blog title/description once. - Rewrite `get_user_rss` and `get_user_atom` to resolve the profile, build a `FeedData`, and map it into their own crate's builders. A field belonging to an entry or the feed now has one home. - Fold the content-type header handling into a shared `feed_response` helper. Output is unchanged — this is a pure restructuring. `format`, `clippy`, and `ci` all pass. Closes #101.
web: Extract shared feed assembly into a FeedData DTO
Some checks failed
ci/woodpecker/push/clippy Pipeline was canceled
ci/woodpecker/push/test Pipeline was canceled
626fdb9c6a
The RSS and Atom feed handlers duplicated their profile resolution,
per-post permalink construction, blog URL building, and content-type
plumbing, with only the format-specific builders differing. That
duplication had already produced drift (see #94).

Move the shared, format-agnostic feed data behind a FeedData DTO with a
from_profile constructor, so each handler just maps it into its own
crate's builders. A field belonging to an entry or the feed now has one
home.

Closes #101.
web: Inline the single-use feed_response helper
Some checks failed
ci/woodpecker/push/clippy Pipeline was successful
ci/woodpecker/push/test Pipeline was canceled
35a6254a3d
Each handler sets its own content type once, so the shared helper added
indirection without earning it. Fold the header building back into the
two callers.
web: Move feed rendering onto FeedData as to_rss/to_atom_string
All checks were successful
ci/woodpecker/push/clippy Pipeline was successful
ci/woodpecker/push/test Pipeline was successful
886d5847e6
Give FeedData responsibility for rendering itself to each format, so the
handlers reduce to resolve, render, and set the content type. Rendering
is now unit-testable in isolation without going through an HTTP handler.
web: Test RSS and Atom feed rendering
All checks were successful
ci/woodpecker/push/clippy Pipeline was successful
ci/woodpecker/push/test Pipeline was successful
eeb6743520
Cover FeedData::to_rss_string and to_atom_string by rendering a sample
feed, parsing it back through each crate's reader, and asserting the
channel/feed and entry fields survive the round trip.

Enable the rss crate's validation feature and run Channel::validate on
the RSS output. atom_syndication ships no validator, so a successful
round-trip parse is the strongest check available there.
rosa merged commit 38b5acbbd2 into main 2026-07-05 00:35:51 +00:00
rosa deleted branch refactor/shared-feed-assembly 2026-07-05 00:35:51 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
rosa/vernier!104
No description provided.