⚠ This page is served via a proxy. Original site: https://github.com
This service does not collect credentials or authentication data.
Skip to content

Conversation

Copy link

Copilot AI commented Nov 24, 2025

Reduces duplication between GuidScrubber.cs and DirectoryReplacements_StringBuilder.cs by extracting the common Match struct and match application logic.

Changes

  • New StringBuilderChunkMatcher.cs: Contains shared Match struct and ApplyMatches method
  • Updated GuidScrubber.cs: Uses common Match struct via type alias, delegates to ApplyMatches
  • Updated DirectoryReplacements_StringBuilder.cs: Same refactoring

Usage

using Match = StringBuilderChunkMatcher.Match;

// Collect matches
matches.Add(new Match(startPosition, length, replacement));

// Apply all matches (sorted by descending index)
StringBuilderChunkMatcher.ApplyMatches(builder, matches);

Not Changed

DateScrubber.cs uses inline replacement during scanning rather than collecting matches, so it doesn't benefit from this refactor. The carryover buffer management was left in place as abstracting it would add complexity without meaningful benefit given the Span/stackalloc constraints.

Original prompt

Refactor common code across GuidScrubber.cs, DateScrubber.cs, and DirectoryReplacements_StringBuilder.cs

These three files have significant duplication around:

  1. Cross-chunk matching logic for StringBuilder chunks
  2. Carryover buffer management (tracking last N chars between chunks)
  3. Match collection and application (sorting by descending position and applying replacements)
  4. Similar Match struct definitions

Please create a new helper class called StringBuilderChunkMatcher.cs in the same directory (src/Verify/Serialization/Scrubbers/) that contains:

  1. A common Match struct that can be used by all scrubbers:
internal readonly struct Match(int index, int length, string value)
{
    public readonly int Index = index;
    public readonly int Length = length;
    public readonly string Value = value;
}
  1. A method ApplyMatches that handles the common logic of sorting and applying matches:
public static void ApplyMatches(StringBuilder builder, List<Match> matches)
{
    var orderByDescending = matches.OrderByDescending(_ => _.Index);
    foreach (var match in orderByDescending)
    {
        builder.Overwrite(match.Value, match.Index, match.Length);
    }
}
  1. Helper methods for cross-chunk buffer management that can be reused:
  • InitializeCarryoverBuffer - initialize the carryover buffer and related tracking variables
  • UpdateCarryoverBuffer - update the carryover buffer at the end of each chunk iteration
  • ProcessCarryover - common pattern for checking matches that span chunks

Then update GuidScrubber.cs, DateScrubber.cs, and DirectoryReplacements_StringBuilder.cs to use these common helpers instead of duplicating the logic.

The goal is to reduce duplication while maintaining the same functionality and performance characteristics (using stackalloc buffers, etc.).

This pull request was created as a result of the following prompt from Copilot chat.

Refactor common code across GuidScrubber.cs, DateScrubber.cs, and DirectoryReplacements_StringBuilder.cs

These three files have significant duplication around:

  1. Cross-chunk matching logic for StringBuilder chunks
  2. Carryover buffer management (tracking last N chars between chunks)
  3. Match collection and application (sorting by descending position and applying replacements)
  4. Similar Match struct definitions

Please create a new helper class called StringBuilderChunkMatcher.cs in the same directory (src/Verify/Serialization/Scrubbers/) that contains:

  1. A common Match struct that can be used by all scrubbers:
internal readonly struct Match(int index, int length, string value)
{
    public readonly int Index = index;
    public readonly int Length = length;
    public readonly string Value = value;
}
  1. A method ApplyMatches that handles the common logic of sorting and applying matches:
public static void ApplyMatches(StringBuilder builder, List<Match> matches)
{
    var orderByDescending = matches.OrderByDescending(_ => _.Index);
    foreach (var match in orderByDescending)
    {
        builder.Overwrite(match.Value, match.Index, match.Length);
    }
}
  1. Helper methods for cross-chunk buffer management that can be reused:
  • InitializeCarryoverBuffer - initialize the carryover buffer and related tracking variables
  • UpdateCarryoverBuffer - update the carryover buffer at the end of each chunk iteration
  • ProcessCarryover - common pattern for checking matches that span chunks

Then update GuidScrubber.cs, DateScrubber.cs, and DirectoryReplacements_StringBuilder.cs to use these common helpers instead of duplicating the logic.

The goal is to reduce duplication while maintaining the same functionality and performance characteristics (using stackalloc buffers, etc.).


💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

Copilot AI changed the title [WIP] Refactor common code in StringBuilder scrubbers Extract common Match struct and ApplyMatches logic into StringBuilderChunkMatcher Nov 24, 2025
Copilot AI requested a review from SimonCropp November 24, 2025 23:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants