Skip to content

feat: support custom formatting in interpolated string handlers#241

Merged
skarllot merged 4 commits intomainfrom
feat/interpolation-format
Feb 28, 2026
Merged

feat: support custom formatting in interpolated string handlers#241
skarllot merged 4 commits intomainfrom
feat/interpolation-format

Conversation

@skarllot
Copy link
Copy Markdown
Owner

@skarllot skarllot commented Feb 28, 2026

Pull Request

The issue or feature being addressed

Adds support for custom format strings in interpolated string handlers of SourceTextWriter, enabling callers to pass format specifiers (e.g., {value:X2}) directly via string interpolation.

Details on the issue fix or feature implementation

  • Added AppendFormatted<T>(T value, string? format) overload to the InterpolatedStringHandler in SourceTextWriter.Interpolation.cs to handle format strings in interpolated expressions
  • Extended Write and WriteLine methods in SourceTextWriter.Write.cs and SourceTextWriter.WriteLine.cs to support format parameters
  • Added new test files SourceTextWriterTest.WriteFormat.cs and SourceTextWriterTest.WriteLineFormat.cs covering the new formatting behaviour
  • Updated existing tests in SourceTextWriterTest.Write.cs and SourceTextWriterTest.WriteLine.cs to align with the refactored method signatures
  • Minor refactoring in CSharp integration tests (CodeWriterDispatcherGenericTest.cs, CodeWriterDispatcherTest.cs) and SourceProductionContextRunner.cs

Confirm the following

  • I started this PR by branching from the head of the default branch
  • I have targeted the PR to merge into the default branch
  • I have included unit tests for the issue/feature
  • I have successfully run a local build

Summary by CodeRabbit

  • New Features

    • Write and WriteLine now accept an optional format parameter for many value and object types, enabling custom numeric/date formatting and formatted interpolated strings.
  • Tests

    • Added broad, data-driven tests validating formatted outputs, interpolated-format behavior, and null handling for write/writeline paths.
  • Style

    • Repository-wide whitespace and formatting cleanups.
  • Documentation

    • Clarified project nullability guidance.

@skarllot skarllot added the enhancement New feature or request label Feb 28, 2026
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Feb 28, 2026

Warning

Rate limit exceeded

@skarllot has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 9 minutes and 24 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between d154484 and 581eaa4.

📒 Files selected for processing (1)
  • README.md
📝 Walkthrough

Walkthrough

Adds format-aware overloads for Write, WriteLine, and AppendFormatted across primitive, nullable, object, and generic types; updates existing overloads to delegate to the new format-enabled variants. Tests are consolidated and expanded to validate formatting; minor build/test project formatting and package updates applied.

Changes

Cohort / File(s) Summary
Core formatting API
src/InterpolationCodeWriter/SourceTextWriter.Write.cs, src/InterpolationCodeWriter/SourceTextWriter.WriteLine.cs, src/InterpolationCodeWriter/SourceTextWriter.Interpolation.cs
Introduces extensive format-aware overloads for Write, WriteLine, and AppendFormatted for primitives, nullable variants, object and generic types. Existing single-arg overloads now delegate to format-aware versions; numeric ToString calls now respect format parameters. Public API surface expanded.
Tests — new/expanded format tests
tests/InterpolationCodeWriter.Tests/SourceTextWriterTest.WriteFormat.cs, tests/InterpolationCodeWriter.Tests/SourceTextWriterTest.WriteLineFormat.cs, tests/InterpolationCodeWriter.Tests/SourceTextWriterTest.Interpolation.cs
Adds data-driven tests and TheoryData covering numeric, nullable, enum, DateTime, and interpolated formatting scenarios to validate new formatting behavior.
Tests — consolidation & refactor
tests/InterpolationCodeWriter.Tests/SourceTextWriterTest.Write.cs, tests/InterpolationCodeWriter.Tests/SourceTextWriterTest.WriteLine.cs, tests/InterpolationCodeWriter.CSharp.Tests/CodeWriterDispatcherGenericTest.cs, tests/InterpolationCodeWriter.CSharp.Tests/CodeWriterDispatcherTest.cs, tests/InterpolationCodeWriter.CSharp.Tests/Fakes/SourceProductionContextRunner.cs
Consolidates many per-type tests into data-driven tests; refactors test lambdas/asserts to inline single-line forms; no behavior changes to tests beyond coverage consolidation.
Test project package updates & locks
tests/Directory.Packages.props, tests/InterpolationCodeWriter.CSharp.Tests/*.csproj, tests/InterpolationCodeWriter.CSharp.Tests/packages.lock.json, tests/InterpolationCodeWriter.Tests/*.csproj, tests/InterpolationCodeWriter.Tests/packages.lock.json
Adds coverlet.msbuild and coverlet.collector entries; adjusts project package entries and lockfiles to include Coverlet for test coverage.
Build & project formatting
Directory.Build.props, modules/polyfill.props, SourceGenerators.slnx, src/InterpolationCodeWriter.CSharp.Sources/build/...targets
Whitespace, indentation, and minor XML reformatting changes only; no semantic or functional build changes detected.
Docs
CLAUDE.md
Minor wording change describing nullable settings (documentation only).

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested reviewers

  • fgodoy-lepaho

Poem

🐰
I nibble on format strings bright,
Bytes and floats now print just right,
WriteLine hops, AppendFormatted sings,
Tests consolidated with tiny springs,
A carrot-coded, joyful byte!

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 76.19% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The PR title clearly summarizes the main feature: adding support for custom formatting in interpolated string handlers, which aligns with the primary changes in SourceTextWriter.
Description check ✅ Passed The PR description comprehensively addresses all required template sections: issue/feature addressed, implementation details with specific file changes, and all confirmation checklist items are completed.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/interpolation-format

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@tests/InterpolationCodeWriter.Tests/SourceTextWriterTest.WriteLine.cs`:
- Around line 5-13: This test file is using nullable annotations but lacks a
file-level opt-in; add the nullable context directive by placing "#nullable
enable" at the top of the file so the nullable checks apply for the tests
(affects the code around the WriteLineValueAppendsStringRepresentation test and
any usages of SourceTextWriter and the MemberData methods like
WriteLinePrimitiveCases/WriteLineNullableValueCases).

ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b359091 and b304b7e.

📒 Files selected for processing (16)
  • Directory.Build.props
  • SourceGenerators.slnx
  • modules/polyfill.props
  • src/InterpolationCodeWriter.CSharp.Sources/build/Raiqub.Generators.InterpolationCodeWriter.CSharp.Sources.targets
  • src/InterpolationCodeWriter/SourceTextWriter.Interpolation.cs
  • src/InterpolationCodeWriter/SourceTextWriter.Write.cs
  • src/InterpolationCodeWriter/SourceTextWriter.WriteLine.cs
  • tests/Directory.Packages.props
  • tests/InterpolationCodeWriter.CSharp.Tests/CodeWriterDispatcherGenericTest.cs
  • tests/InterpolationCodeWriter.CSharp.Tests/CodeWriterDispatcherTest.cs
  • tests/InterpolationCodeWriter.CSharp.Tests/Fakes/SourceProductionContextRunner.cs
  • tests/InterpolationCodeWriter.Tests/SourceTextWriterTest.Interpolation.cs
  • tests/InterpolationCodeWriter.Tests/SourceTextWriterTest.Write.cs
  • tests/InterpolationCodeWriter.Tests/SourceTextWriterTest.WriteFormat.cs
  • tests/InterpolationCodeWriter.Tests/SourceTextWriterTest.WriteLine.cs
  • tests/InterpolationCodeWriter.Tests/SourceTextWriterTest.WriteLineFormat.cs
💤 Files with no reviewable changes (1)
  • Directory.Build.props

@codecov
Copy link
Copy Markdown

codecov Bot commented Feb 28, 2026

Welcome to Codecov 🎉

Once you merge this PR into your default branch, you're all set! Codecov will compare coverage reports and display results in all future pull requests.

Thanks for integrating Codecov - We've got you covered ☂️

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (2)
tests/InterpolationCodeWriter.CSharp.Tests/InterpolationCodeWriter.CSharp.Tests.csproj (1)

14-27: LGTM! Coverage tooling additions are correctly configured.

The addition of coverlet.msbuild alongside coverlet.collector provides comprehensive code coverage support. Package references correctly use central package management without explicit versions.

Minor nit (optional): The element ordering within coverlet.msbuild (lines 19-20) is reversed compared to coverlet.collector (lines 15-16). Consider aligning for consistency:

✨ Optional consistency fix
     <PackageReference Include="coverlet.msbuild">
-      <PrivateAssets>all</PrivateAssets>
       <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
+      <PrivateAssets>all</PrivateAssets>
     </PackageReference>

,

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@tests/InterpolationCodeWriter.CSharp.Tests/InterpolationCodeWriter.CSharp.Tests.csproj`
around lines 14 - 27, The two PackageReference blocks should be consistent: in
the coverlet.msbuild PackageReference (the element with
Include="coverlet.msbuild") swap the order of the child elements so they match
coverlet.collector (place the IncludeAssets element before the PrivateAssets
element); update the coverlet.msbuild PackageReference to have IncludeAssets
then PrivateAssets to maintain consistent element ordering across both package
references.
tests/InterpolationCodeWriter.Tests/InterpolationCodeWriter.Tests.csproj (1)

13-20: Both coverlet.collector and coverlet.msbuild are included.

Having both coverage packages provides flexibility for different collection mechanisms (data collector vs. MSBuild integration), but they serve overlapping purposes. If your CI/CD pipeline only uses one approach, consider keeping only the relevant package to reduce dependencies.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/InterpolationCodeWriter.Tests/InterpolationCodeWriter.Tests.csproj`
around lines 13 - 20, The project currently references both coverlet.collector
and coverlet.msbuild; decide which coverage mechanism your CI uses and remove
the unused package reference to avoid redundant dependencies—either keep
coverlet.collector (data collector approach) or keep coverlet.msbuild (MSBuild
integration) and delete the other PackageReference entry for coverlet.collector
or coverlet.msbuild in the project file.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In
`@tests/InterpolationCodeWriter.CSharp.Tests/InterpolationCodeWriter.CSharp.Tests.csproj`:
- Around line 14-27: The two PackageReference blocks should be consistent: in
the coverlet.msbuild PackageReference (the element with
Include="coverlet.msbuild") swap the order of the child elements so they match
coverlet.collector (place the IncludeAssets element before the PrivateAssets
element); update the coverlet.msbuild PackageReference to have IncludeAssets
then PrivateAssets to maintain consistent element ordering across both package
references.

In `@tests/InterpolationCodeWriter.Tests/InterpolationCodeWriter.Tests.csproj`:
- Around line 13-20: The project currently references both coverlet.collector
and coverlet.msbuild; decide which coverage mechanism your CI uses and remove
the unused package reference to avoid redundant dependencies—either keep
coverlet.collector (data collector approach) or keep coverlet.msbuild (MSBuild
integration) and delete the other PackageReference entry for coverlet.collector
or coverlet.msbuild in the project file.

ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b304b7e and d154484.

📒 Files selected for processing (6)
  • CLAUDE.md
  • tests/Directory.Packages.props
  • tests/InterpolationCodeWriter.CSharp.Tests/InterpolationCodeWriter.CSharp.Tests.csproj
  • tests/InterpolationCodeWriter.CSharp.Tests/packages.lock.json
  • tests/InterpolationCodeWriter.Tests/InterpolationCodeWriter.Tests.csproj
  • tests/InterpolationCodeWriter.Tests/packages.lock.json
✅ Files skipped from review due to trivial changes (1)
  • CLAUDE.md
🚧 Files skipped from review as they are similar to previous changes (1)
  • tests/Directory.Packages.props

@skarllot skarllot merged commit ba62075 into main Feb 28, 2026
7 checks passed
@skarllot skarllot deleted the feat/interpolation-format branch February 28, 2026 22:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants