domain: comrak options duplicated between Content::to_html and Biography::to_html and rebuilt per call #66
Labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
rosa/vernier#66
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Found during a code review of the
domaincrate.Location:
crates/domain/src/models/post.rs:322andcrates/domain/src/models/user.rs:153Type: Cleanup — duplication + wasted work
Problem
Content::to_htmlandBiography::to_htmlcontain byte-identical ~25-line comrak Extension/Options blocks (same 12 extensions in the same order), each rebuilt on every render call with no shared static or helper.Cost
Enabling a new extension for posts but not bios (or vice versa) makes the same Markdown render differently on the same page, and every render reconstructs the same Options value.
Suggested fix
Build the options once in a
static OPTIONS: LazyLock<comrak::Options>and expose a singlerender_markdown(&str) -> Stringhelper both methods delegate to.Agent Brief
Category: enhancement
Summary: Hoist the duplicated comrak
Optionsinto a single shared build-once static used by both markdown-rendering methodsCurrent behavior:
Content::to_html(post content) andBiography::to_html(user bio) in thedomaincrate each construct an identicalcomrak::Optionsvalue inline —the same 12 extensions in the same order — and rebuild it on every render
call. The two blocks are byte-identical copies with no shared definition, so
enabling an extension in one place but not the other would make the same
Markdown render differently depending on where it appears.
Desired behavior:
Both
to_htmlmethods reference one shared, crate-internalOptionsvaluethat is built at most once per process (e.g. a
static OPTIONS: LazyLock<comrak::Options>, matching the existingLazyLock<Selector>idiom used for webmention HTML parsing in this crate).Each method continues to call
comrak::markdown_to_htmldirectly, passing areference to the shared options. Do not introduce a
render_markdown-stylewrapper function — the maintainer explicitly decided against one; only the
options value is shared.
Key interfaces:
Content::to_html(&self) -> StringandBiography::to_html(&self) -> String— signatures and rendered output unchanged
public API), placed where both model modules can reach it
footnotes, highlight, inline_footnotes, insert, multiline_block_quotes,
strikethrough, subscript, superscript, table, underline; all other options
remain
Default::default()Acceptance criteria:
domaincrate; bothto_htmlmethods use itrender_markdownwrapper function is introducedciandclippymise tasks passOut of scope:
Content::parse/Biography::parseor other validation logicdomaincrateImplemented in commit
4522ac1: the 12-extension comrak options block now lives in a single pub(crate)static MARKDOWN_OPTIONS: LazyLock<comrak::Options>in the domain crate's models module, and bothContent::to_htmlandBiography::to_htmlpass it tocomrak::markdown_to_htmldirectly — no wrapper function, per the agent brief.