Skip to content

Refactor attach_orphan_specifiers to use state machine with Peekable iterator #102

@sourcery-ai

Description

@sourcery-ai

The current implementation of the attach_orphan_specifiers function uses a reverse-search (.rev().find(...)) and out.remove(idx) to attach orphan specifiers, which adds unnecessary complexity to the code. It has been suggested to refactor this logic by rewriting the loop as a state machine using a Peekable iterator. This approach would allow the function to look ahead for a "language only" line followed by a code fence (`````), and handle the attachment in a single pass, eliminating the need for backtracking and buffer manipulation.

The proposed refactor would:

  • Remove the reverse-search and buffer removal hack.
  • Use a Peekable iterator to match language specifier + fence pairs in one pass.
  • Preserve all existing behavior and tests.

Here is a sample implementation for reference:

pub fn attach_orphan_specifiers(lines: &[String]) -> Vec<String> {
    let mut out = Vec::with_capacity(lines.len());
    let mut in_fence = false;
    let mut iter = lines.iter().peekable();

    while let Some(line) = iter.next() {
        let trimmed = line.trim();

        // If we’re not already inside a fence, and we see a
        // bare language line + next line is exactly "```",
        // emit "```<lang>" and consume the fence in one shot.
        if !in_fence && ORPHAN_LANG_RE.is_match(trimmed) {
            if iter.peek().map(|next| next.trim() == "```").unwrap_or(false) {
                out.push(format!("```{trimmed}"));
                iter.next();             // consume the fence
                in_fence = true;         // now inside
                continue;
            }
        }

        // Toggle fence state on every line that starts a fence
        if trimmed.starts_with("```") {
            in_fence = !in_fence;
        }

        // Otherwise just copy the line verbatim
        out.push(line.clone());
    }

    out
}

Action items:

  • Refactor attach_orphan_specifiers to use a state machine with a Peekable iterator as described above.
  • Remove the reverse-search and buffer removal logic.
  • Ensure all existing tests pass and behavior is preserved.

This change should make the code easier to follow and maintain.


I created this issue for @leynos from #100 (comment).

Tips and commands

Getting Help

Metadata

Metadata

Assignees

No one assigned

    Labels

    lowAin't annoying anyone but the QA department

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions