Skip to content

semantics: explicit mutating APIs, safe replacements#186

Merged
ReneWerner87 merged 10 commits intomasterfrom
toLowerToUpper
Feb 14, 2026
Merged

semantics: explicit mutating APIs, safe replacements#186
ReneWerner87 merged 10 commits intomasterfrom
toLowerToUpper

Conversation

@ReneWerner87
Copy link
Copy Markdown
Member

@ReneWerner87 ReneWerner87 commented Feb 11, 2026

Why I changed this

The previous setup made it too easy to mix up copy-based vs in-place behavior.
For string/byte case conversion, that distinction is important for correctness and for performance expectations.

What changed

  • Introduced/kept a clear split between:
    • non-mutating variants (safe default behavior)
    • mutating variants (explicit in-place behavior)
  • Kept non-mutating functions as exact replacements from a caller perspective.
  • Made mutating functions intentionally explicit in naming/docs, so side effects are obvious.
  • Reduced internal duplication by reusing shared ASCII mapping logic where possible.
  • Preserved hot-path performance characteristics while simplifying maintenance.

Outcome

  • API behavior is clearer at call sites.
  • Fewer surprises around accidental mutation.
  • Easier to maintain and extend without re-implementing the same mapping loops in multiple places.

Summary by CodeRabbit

  • New Features

    • Added additional case-conversion helpers for strings and byte slices, including non-mutating and in-place variants.
  • Tests

    • Expanded unit tests for mutation behavior and added table-driven benchmarks covering safe and unsafe paths.
  • Documentation

    • Reformatted README benchmark sections into a text presentation; reorganized and extended benchmark groups and results.
  • Refactor

    • Consolidated and delegated case-conversion implementations to shared utilities for consistency.

Copilot AI review requested due to automatic review settings February 11, 2026 23:26
@ReneWerner87 ReneWerner87 requested a review from a team as a code owner February 11, 2026 23:26
@ReneWerner87 ReneWerner87 requested review from efectn, gaby and sixcolors and removed request for a team February 11, 2026 23:26
@gemini-code-assist
Copy link
Copy Markdown
Contributor

Summary of Changes

Hello @ReneWerner87, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request enhances the utility library by clarifying the semantics of string and byte slice case conversion. It introduces explicit mutating functions for performance-critical scenarios while ensuring that the default conversion functions are non-mutating. This change improves API predictability, reduces the risk of unintended side effects, and streamlines internal code, contributing to a more robust and maintainable codebase.

Highlights

  • Explicit Mutating APIs: Introduced new ToLowerBytesMut, ToUpperBytesMut, ToLowerMut, and ToUpperMut functions for in-place (mutating) ASCII byte slice and string case conversion, clearly distinguishing them from non-mutating variants.
  • Non-Mutating Defaults: Refactored existing ToLowerBytes and ToUpperBytes functions to ensure they are non-mutating, always returning a new byte slice or string, thus providing a safe default behavior.
  • Improved Benchmarking: Updated all Go benchmarks across various utility functions to use the idiomatic for b.Loop() syntax, ensuring more accurate and reliable performance measurements.
  • Reduced Duplication: Optimized internal logic by reusing shared ASCII mapping where possible, simplifying maintenance without compromising hot-path performance.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Changelog
  • README.md
    • Updated benchmark results to reflect the new mutating variants and general performance changes.
  • bytes.go
    • Modified ToLowerBytes to be non-mutating, returning a new byte slice.
    • Added ToLowerBytesMut for in-place lowercasing of byte slices.
    • Modified ToUpperBytes to be non-mutating, returning a new byte slice.
    • Added ToUpperBytesMut for in-place uppercasing of byte slices.
    • Updated comments to clearly indicate mutating vs. non-mutating behavior.
  • bytes_test.go
    • Added new tests (Test_ToLowerBytes_NoMutation, Test_ToUpperBytes_NoMutation) to verify non-mutating behavior.
    • Added new tests (Test_ToLowerBytesMut, Test_ToUpperBytesMut) to confirm in-place mutation.
    • Refactored Benchmark_ToLowerBytes and Benchmark_ToUpperBytes to use benchmarkCoreCases and include fiber/mut benchmarks.
    • Updated Benchmark_AddTrailingSlashBytes to use for b.Loop().
  • byteseq_test.go
    • Updated Benchmark_EqualFoldBytes and Benchmark_EqualFold to use for b.Loop().
  • common_test.go
    • Updated Benchmark_ConvertToBytes, Benchmark_GenerateSecureToken, and Benchmark_TokenGenerators to use for b.Loop().
  • convert_test.go
    • Updated Benchmark_ToString, Benchmark_UnsafeBytes, Benchmark_UnsafeString, and Benchmark_ByteSize to use for b.Loop().
  • format_test.go
    • Updated all Benchmark_Format* and Benchmark_Append* functions to use for b.Loop().
  • http_test.go
    • Updated Benchmark_GetMIME, Benchmark_ParseVendorSpecificContentType, and Benchmark_StatusMessage to use for b.Loop().
  • ips_test.go
    • Updated Benchmark_IsIPv4 and Benchmark_IsIPv6 to use for b.Loop().
  • parse_test.go
    • Updated all Benchmark_Parse* functions to use for b.Loop().
  • strings.go
    • Added ToLowerMut for unsafe in-place lowercasing of strings.
    • Added ToUpperMut for unsafe in-place uppercasing of strings.
  • strings_test.go
    • Simplified benchmarkCoreCases test data.
    • Added new tests (Test_ToLowerMut, Test_ToUpperMut) for mutating string functions.
    • Updated Benchmark_ToUpper and Benchmark_ToLower to include fiber/mut benchmarks.
    • Updated Benchmark_AddTrailingSlashString to use for b.Loop().
  • time_test.go
    • Updated Benchmark_CalculateTimestamp to use for b.Loop().
  • xml_test.go
    • Updated Benchmark_GolangXMLEncoder, Benchmark_DefaultXMLEncoder, and Benchmark_DefaultXMLDecoder to use for b.Loop().
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@codecov
Copy link
Copy Markdown

codecov bot commented Feb 11, 2026

Codecov Report

❌ Patch coverage is 89.78495% with 19 lines in your changes missing coverage. Please review.
✅ Project coverage is 84.15%. Comparing base (e1a1c4c) to head (7d2fef0).
⚠️ Report is 14 commits behind head on master.

Files with missing lines Patch % Lines
bytes/case.go 91.30% 6 Missing and 2 partials ⚠️
strings/case.go 92.85% 4 Missing and 2 partials ⚠️
bytes.go 0.00% 2 Missing ⚠️
scripts/format_benchmarks.go 0.00% 2 Missing ⚠️
strings.go 66.66% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master     #186      +/-   ##
==========================================
- Coverage   84.52%   84.15%   -0.37%     
==========================================
  Files          12       14       +2     
  Lines        1053     1155     +102     
==========================================
+ Hits          890      972      +82     
- Misses        136      152      +16     
- Partials       27       31       +4     
Flag Coverage Δ
unittests 84.15% <89.78%> (-0.37%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Feb 11, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Replaces in-file ASCII case-conversion implementations with new internal packages/tables and unsafe helpers, adds dedicated bytes/strings case routines (safe and unsafe variants), updates top-level wrappers to delegate, and refactors tests/benchmarks and README benchmark formatting. No public API signatures changed.

Changes

Cohort / File(s) Summary
Top-level delegations & imports
bytes.go, strings.go
Replaced prior in-file ToLower/ToUpper logic with delegating wrappers to new packages (import aliases added); comments updated to indicate deprecation/back-compat; signatures unchanged.
New package implementations
bytes/case.go, strings/case.go
Added ASCII-focused implementations: ToLower, ToUpper, UnsafeToLower, UnsafeToUpper (non-mutating and in-place variants) with loop unrolling and table-driven mapping.
Internal data & unsafe helpers
internal/caseconv/caseconv.go, internal/unsafeconv/unsafeconv.go
Introduced exported case mapping tables (ToLowerTable, ToUpperTable) and zero-allocation conversions (UnsafeString, UnsafeBytes).
Byte/compare and conversion refactors
byteseq.go, common.go, convert.go
Removed local case tables, switched to caseconv tables, and replaced direct unsafe conversions with unsafeconv helpers.
Tests & benchmarks
bytes_test.go, strings_test.go, bytes/case_test.go, strings/case_test.go, format_test.go, convert_test.go, xml_test.go
Added/expanded tests for mutation behavior; converted many benchmarks to table-driven structure; standardized loop variable naming (in); added fiber/unsafe benchmark sub-cases.
Docs & formatting tooling
README.md, scripts/format_benchmarks.go
Changed benchmark fence detection from go to text and reorganized README benchmark sections (new Case Conversion grouping and reformatted benchmark output).

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested reviewers

  • gaby
  • sixcolors
  • efectn

Poem

"I hop through bytes and strings with care,
I flip each case and breathe the air.
Unsafe hops for speed I lend,
Safe copies keep the program mend.
Benchmarks clap — a rabbit's flair! 🐇"

🚥 Pre-merge checks | ✅ 2 | ❌ 2
❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Merge Conflict Detection ⚠️ Warning ❌ Merge conflicts detected (14 files):

⚔️ README.md (content)
⚔️ bytes.go (content)
⚔️ bytes_test.go (content)
⚔️ byteseq.go (content)
⚔️ common.go (content)
⚔️ convert.go (content)
⚔️ convert_test.go (content)
⚔️ format_test.go (content)
⚔️ go.mod (content)
⚔️ go.sum (content)
⚔️ scripts/format_benchmarks.go (content)
⚔️ strings.go (content)
⚔️ strings_test.go (content)
⚔️ xml_test.go (content)

These conflicts must be resolved before merging into master.
Resolve conflicts locally and push changes to this branch.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'semantics: explicit mutating APIs, safe replacements' accurately and specifically describes the main objective of the PR: separating mutating from non-mutating case conversion APIs with explicit naming and providing safe alternatives.

✏️ 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 toLowerToUpper

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
Contributor

@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

🤖 Fix all issues with AI agents
In `@strings_test.go`:
- Around line 165-173: The "fiber/mut" sub-benchmark inside Benchmark_ToUpper is
missing b.ResetTimer(), so the setup allocation of template/work is being
measured; add a call to b.ResetTimer() after preparing template and work (before
the for loop) in the same sub-benchmark that calls
ToUpperMut(UnsafeString(work)) so timing matches Benchmark_ToLower's "fiber/mut"
case; locate the block using the identifiers Benchmark_ToUpper, "fiber/mut",
ToUpperMut, and UnsafeString and insert b.ResetTimer() immediately before the
benchmarking loop.
🧹 Nitpick comments (6)
xml_test.go (1)

91-93: b.ResetTimer() is redundant when using b.Loop().

"The b.ResetTimer at the loop's start and b.StopTimer at its end are integrated into testing.B.Loop", so the explicit b.ResetTimer() on line 92 (and similarly on lines 114 and 131) can be removed. Not harmful, but unnecessary noise.

🧹 Suggested cleanup (applies to all three benchmarks in this file)
 	b.ReportAllocs()
-	b.ResetTimer()
 	for b.Loop() {
time_test.go (1)

79-81: bb.ResetTimer() is redundant with bb.Loop().

Same as in xml_test.gob.Loop() automatically resets the timer on its first call. The explicit bb.ResetTimer() calls on lines 80, 88, 97, and 107 can be removed.

byteseq_test.go (1)

370-377: b.ResetTimer() is redundant with b.Loop().

Lines 372 and 382 (and similarly 400, 410 in Benchmark_TrimSpaceBytes) have explicit b.ResetTimer() calls that are unnecessary when using b.Loop().

convert_test.go (1)

289-299: LGTM with minor nit: b.ResetTimer() on line 293 is redundant with b.Loop().

The migration is correct. The Benchmark_ToString_concurrency function properly retains pb.Next() for RunParallel, which is the correct pattern.

bytes_test.go (2)

88-111: Inconsistent benchmark loop style: mixed b.Loop() and for n := 0; n < b.N; n++.

Within Benchmark_ToLowerBytes, the "fiber/mut" sub-benchmark (line 99) uses for b.Loop() while "fiber" (line 90) and "default" (line 107) use for n := 0; n < b.N; n++. The same inconsistency exists in Benchmark_ToUpperBytes (lines 126, 135, 143), where all three use the manual loop. Since the PR objective is to modernize benchmark loops, consider using b.Loop() consistently across all sub-benchmarks, or keeping the manual style consistently — mixing them makes the benchmarks harder to compare.


81-82: tc := tc is unnecessary in Go 1.22+.

Since Go 1.22, loop variables are scoped per iteration, so this re-capture is no longer needed. Same applies to Benchmark_ToUpperBytes at line 118.

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e9c6da5 and 109a67d.

📒 Files selected for processing (14)
  • README.md
  • bytes.go
  • bytes_test.go
  • byteseq_test.go
  • common_test.go
  • convert_test.go
  • format_test.go
  • http_test.go
  • ips_test.go
  • parse_test.go
  • strings.go
  • strings_test.go
  • time_test.go
  • xml_test.go
🧰 Additional context used
🧬 Code graph analysis (8)
common_test.go (1)
common.go (2)
  • GenerateSecureToken (72-91)
  • UUIDv4 (54-60)
ips_test.go (1)
ips.go (2)
  • IsIPv4 (15-45)
  • IsIPv6 (49-143)
time_test.go (1)
time.go (1)
  • Timestamp (18-20)
bytes_test.go (2)
bytes.go (4)
  • ToLowerBytes (8-33)
  • ToUpperBytes (67-92)
  • ToLowerBytesMut (37-64)
  • ToUpperBytesMut (96-123)
strings.go (2)
  • ToLower (8-36)
  • ToUpper (47-76)
strings.go (2)
bytes.go (2)
  • ToLowerBytesMut (37-64)
  • ToUpperBytesMut (96-123)
convert.go (1)
  • UnsafeBytes (26-29)
byteseq_test.go (1)
byteseq.go (4)
  • EqualFold (8-54)
  • TrimRight (83-89)
  • TrimLeft (57-63)
  • Trim (66-80)
convert_test.go (1)
convert.go (2)
  • UnsafeBytes (26-29)
  • UnsafeString (18-23)
http_test.go (1)
http.go (2)
  • ParseVendorSpecificContentType (53-95)
  • StatusMessage (104-109)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Agent
  • GitHub Check: Build (1.24.x, windows-latest)
  • GitHub Check: Compare
🔇 Additional comments (14)
ips_test.go (1)

110-141: LGTM — clean migration to b.Loop().

All four benchmark sub-functions correctly use the new for b.Loop() idiom. No redundant timer calls, no other issues.

parse_test.go (1)

55-55: LGTM — consistent b.Loop() migration across all parse benchmarks.

All benchmark sub-functions are correctly updated. b.ReportAllocs() is appropriately retained alongside b.Loop().

Also applies to: 64-64, 73-73, 155-155, 164-164, 173-173

common_test.go (1)

298-337: LGTM — clean b.Loop() adoption across all common benchmarks.

No redundant timer management calls, consistent pattern throughout.

byteseq_test.go (1)

62-63: LGTM — b.Loop() migration for EqualFold and Trim benchmarks.

All loop changes are correct and consistent.

Also applies to: 69-70, 81-82, 88-89

format_test.go (1)

155-156: LGTM — consistent b.Loop() adoption across all format benchmarks.

All changes are mechanical and correct. No redundant timer calls.

Also applies to: 161-162, 184-185, 190-191

strings.go (2)

38-44: LGTM — well-documented unsafe contract.

The implementation is clean: delegates to ToLowerBytesMut(UnsafeBytes(b)) and the unsafe precondition is clearly stated in the doc comment.


78-84: LGTM — mirrors ToLowerMut symmetrically.

http_test.go (1)

57-75: LGTM — benchmark modernized to b.Loop() with expanded MIME coverage.

bytes_test.go (1)

40-78: Good coverage of both non-mutation and in-place mutation contracts.

The tests correctly verify that ToLowerBytes/ToUpperBytes don't modify the input and that ToLowerBytesMut/ToUpperBytesMut share the same backing array.

strings_test.go (2)

112-132: Good tests for the unsafe mutating variants.

Tests correctly create a mutable buffer, wrap it with UnsafeString, call the mutating function, and verify both the returned string and the backing buffer are modified.


46-58: LGTM — compact, representative benchmark case set.

Good coverage of empty, small (GET), mixed-case header, and large strings in different case configurations.

bytes.go (2)

7-33: LGTM — clean non-mutating implementation with unconditional copy.

Always allocating a new dst slice is a sound design choice: it guarantees the input is never modified and avoids subtle aliasing bugs, even at the cost of an allocation when the input is already lowercase.


35-64: LGTM — well-structured in-place mutating variants.

The unrolled loop pattern is consistent between ToLowerBytesMut and ToUpperBytesMut, and correctly handles the remainder after the 4-byte chunks.

Also applies to: 94-123

README.md (1)

22-348: LGTM — benchmark table updated to reflect the new mutating variants and refreshed numbers.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request does a great job of improving API clarity by separating mutating and non-mutating functions for case conversion. The introduction of ...Mut functions makes the in-place behavior explicit, which will help prevent accidental mutations. The associated test and benchmark updates are thorough. I've left a couple of minor suggestions regarding benchmark consistency.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR clarifies case-conversion semantics by introducing explicit in-place (mutating) APIs alongside safe non-mutating defaults, and updates benchmarks/tests to reflect the new split and Go 1.24 benchmark-loop idioms.

Changes:

  • Added explicit mutating string and byte-slice ASCII case-conversion APIs (ToLowerMut/ToUpperMut, ToLowerBytesMut/ToUpperBytesMut) and adjusted tests accordingly.
  • Updated ToLowerBytes/ToUpperBytes to be non-mutating (safe default) implementations.
  • Refactored/updated benchmarks across the repo to use b.Loop() and added new benchmark variants for mutating paths; refreshed benchmark numbers in the README.

Reviewed changes

Copilot reviewed 14 out of 14 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
bytes.go Implements non-mutating byte-slice case conversion and adds explicit in-place variants.
strings.go Adds explicit mutating string case-conversion APIs that operate on mutable-backed strings.
bytes_test.go Adds mutation/non-mutation tests and benchmarks for byte-slice case conversion (incl. mutating variant).
strings_test.go Adds tests/benchmarks for mutating string APIs and simplifies benchmark case set.
format_test.go Updates benchmarks to use b.Loop() for iteration.
parse_test.go Updates benchmarks to use b.Loop() for iteration.
time_test.go Updates benchmarks to use b.Loop() for iteration.
xml_test.go Updates benchmarks to use b.Loop() for iteration.
http_test.go Updates benchmarks to use b.Loop() for iteration.
ips_test.go Updates benchmarks to use b.Loop() for iteration.
convert_test.go Updates benchmarks to use b.Loop() for iteration.
common_test.go Updates benchmarks to use b.Loop() for iteration.
byteseq_test.go Updates benchmarks to use b.Loop() for iteration.
README.md Updates the published benchmark output to reflect new benchmark structure/results.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Copy Markdown
Contributor

@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

🤖 Fix all issues with AI agents
In `@scripts/format_benchmarks.go`:
- Line 49: In the second pass switch that inspects the variable trimmed and
toggles inBlock, replace the stale check trimmed == "```go" with trimmed ==
"```text" so it matches the first-pass detection of text fenced benchmark
blocks; update the conditional that sets inBlock (and any corresponding case
branch) to use "```text" instead of "```go".
🧹 Nitpick comments (1)
bytes_test.go (1)

87-92: Minor inconsistency in benchmark assertions: bytes.Equal vs require.Equal.

Benchmark_ToLowerBytes uses require.True(b, bytes.Equal(want, res)) (line 92) while Benchmark_ToUpperBytes uses require.Equal(b, want, res) (line 126). Both work, but require.Equal gives better failure messages. Consider aligning on require.Equal for both.

Also applies to: 121-126

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3e4a565 and 0417ad4.

📒 Files selected for processing (7)
  • README.md
  • bytes_test.go
  • convert_test.go
  • format_test.go
  • scripts/format_benchmarks.go
  • strings_test.go
  • xml_test.go
🚧 Files skipped from review as they are similar to previous changes (3)
  • README.md
  • strings_test.go
  • format_test.go
🧰 Additional context used
🧬 Code graph analysis (1)
bytes_test.go (1)
bytes.go (4)
  • ToLowerBytes (8-45)
  • ToUpperBytes (79-116)
  • ToLowerBytesMut (49-76)
  • ToUpperBytesMut (120-147)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Build (1.24.x, windows-latest)
  • GitHub Check: Compare
🔇 Additional comments (3)
xml_test.go (1)

93-93: LGTM — consistent loop variable rename.

Cosmetic rename from i to n aligns with the benchmark convention used across the PR.

Also applies to: 115-115, 132-132

convert_test.go (1)

294-294: LGTM — consistent loop variable rename.

Also applies to: 375-375

bytes_test.go (1)

40-78: Well-structured mutation and no-mutation tests.

Good coverage: verifying that ToLowerBytes/ToUpperBytes don't mutate the input, and that the Mut variants share the same backing array. The use of require.Same for pointer identity is a nice touch.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

@ReneWerner87
Copy link
Copy Markdown
Member Author

/gemini review

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

The pull request successfully introduces a clear distinction between mutating and non-mutating case conversion APIs, enhancing both safety and performance. The implementation uses efficient ASCII lookup tables and loop unrolling. I've noted a few opportunities for further optimization in the 'no-change' path for byte slices, potential issues with aliasing in the safe byte slice APIs, and some inconsistencies in loop constructs that affect maintainability.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 18 out of 18 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Copy Markdown
Contributor

@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

🤖 Fix all issues with AI agents
In `@bytes.go`:
- Around line 11-17: Update the deprecation comment for ToLowerBytes (and
similarly ToUpperBytes) to recommend the safe, non-mutating replacement
bytes.ToLower from "github.com/gofiber/utils/v2/bytes" as the primary
alternative, and mention bytes.UnsafeToLower only for callers that explicitly
need in-place mutation for performance; keep the note that this wrapper
preserves backward compatibility by mutating the provided slice and reference
the specific functions ToLowerBytes, ToUpperBytes, bytes.ToLower, and
bytes.UnsafeToLower so readers can find the alternatives easily.
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between bb2fc8c and ebeec6e.

📒 Files selected for processing (1)
  • bytes.go
🧰 Additional context used
🧬 Code graph analysis (1)
bytes.go (1)
bytes/case.go (2)
  • UnsafeToLower (81-104)
  • UnsafeToUpper (108-131)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Compare
🔇 Additional comments (2)
bytes.go (2)

7-9: LGTM!

Good use of an explicit import alias (casebytes) to avoid shadowing the standard library bytes package.


27-32: No changes — looks good.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

sixcolors

This comment was marked as resolved.

Copy link
Copy Markdown
Member

@gaby gaby left a comment

Choose a reason for hiding this comment

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

LGTM

@ReneWerner87 ReneWerner87 merged commit ca61051 into master Feb 14, 2026
18 checks passed
@ReneWerner87 ReneWerner87 deleted the toLowerToUpper branch February 14, 2026 17:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants