From d5476e659e4fbd58970cdd12f9c6002cde54be75 Mon Sep 17 00:00:00 2001
From: Joyless <65855333+Joy-less@users.noreply.github.com>
Date: Thu, 23 Jan 2025 19:38:16 +0000
Subject: [PATCH 1/3] Add TrimPrefix and TrimSuffix
---
.../ValueStringBuilder.Trim.cs | 60 ++++++++++++++-----
.../ValueStringBuilder.cs | 19 ++----
.../ValueStringBuilder.Trim.Tests.cs | 22 +++++++
3 files changed, 70 insertions(+), 31 deletions(-)
diff --git a/src/LinkDotNet.StringBuilder/ValueStringBuilder.Trim.cs b/src/LinkDotNet.StringBuilder/ValueStringBuilder.Trim.cs
index c9a71ee..6da1fba 100644
--- a/src/LinkDotNet.StringBuilder/ValueStringBuilder.Trim.cs
+++ b/src/LinkDotNet.StringBuilder/ValueStringBuilder.Trim.cs
@@ -5,7 +5,7 @@ namespace LinkDotNet.StringBuilder;
public ref partial struct ValueStringBuilder
{
///
- /// Removes a set of whitespace characters from the beginning and ending of this string.
+ /// Removes all whitespace characters from the start and end of this builder.
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Trim()
@@ -33,22 +33,22 @@ public void Trim()
}
///
- /// Removes the specified character from the beginning and end of this string.
+ /// Removes all occurrences of the specified character from the start and end of this builder.
///
- /// The character to remove.
+ /// The character to remove.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public void Trim(char c)
+ public void Trim(char value)
{
// Remove character from the beginning
var start = 0;
- while (start < bufferPosition && buffer[start] == c)
+ while (start < bufferPosition && buffer[start] == value)
{
start++;
}
// Remove character from the end
var end = bufferPosition - 1;
- while (end >= start && buffer[end] == c)
+ while (end >= start && buffer[end] == value)
{
end--;
}
@@ -62,7 +62,7 @@ public void Trim(char c)
}
///
- /// Removes a set of whitespace characters from the beginning of this string.
+ /// Removes all whitespace characters from the start of this builder.
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void TrimStart()
@@ -82,14 +82,14 @@ public void TrimStart()
}
///
- /// Removes the specified character from the beginning of this string.
+ /// Removes all occurrences of the specified character from the start of this builder.
///
- /// The character to remove.
+ /// The character to remove.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public void TrimStart(char c)
+ public void TrimStart(char value)
{
var start = 0;
- while (start < bufferPosition && buffer[start] == c)
+ while (start < bufferPosition && buffer[start] == value)
{
start++;
}
@@ -103,7 +103,7 @@ public void TrimStart(char c)
}
///
- /// Removes a set of whitespace characters from the ending of this string.
+ /// Removes all whitespace characters from the end of this builder.
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void TrimEnd()
@@ -118,18 +118,46 @@ public void TrimEnd()
}
///
- /// Removes the specified character from the end of this string.
+ /// Removes all occurrences of the specified character from the end of this builder.
///
- /// The character to remove.
+ /// The character to remove.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public void TrimEnd(char c)
+ public void TrimEnd(char value)
{
var end = bufferPosition - 1;
- while (end >= 0 && buffer[end] == c)
+ while (end >= 0 && buffer[end] == value)
{
end--;
}
bufferPosition = end + 1;
}
+
+ ///
+ /// Removes the specified sequence of characters from the start of this builder.
+ ///
+ /// The sequence of characters to remove.
+ /// The way to compare the sequences of characters.
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public void TrimPrefix(ReadOnlySpan value, StringComparison comparisonType = StringComparison.Ordinal)
+ {
+ if (AsSpan().StartsWith(value, comparisonType))
+ {
+ Remove(0, value.Length);
+ }
+ }
+
+ ///
+ /// Removes the specified sequence of characters from the end of this builder.
+ ///
+ /// The sequence of characters to remove.
+ /// The way to compare the sequences of characters.
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public void TrimSuffix(ReadOnlySpan value, StringComparison comparisonType = StringComparison.Ordinal)
+ {
+ if (AsSpan().EndsWith(value, comparisonType))
+ {
+ Remove(Length - value.Length, value.Length);
+ }
+ }
}
\ No newline at end of file
diff --git a/src/LinkDotNet.StringBuilder/ValueStringBuilder.cs b/src/LinkDotNet.StringBuilder/ValueStringBuilder.cs
index b190a44..a02a663 100644
--- a/src/LinkDotNet.StringBuilder/ValueStringBuilder.cs
+++ b/src/LinkDotNet.StringBuilder/ValueStringBuilder.cs
@@ -199,26 +199,15 @@ public void EnsureCapacity(int newCapacity)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Remove(int startIndex, int length)
{
+ ArgumentOutOfRangeException.ThrowIfLessThan(length, 0);
+ ArgumentOutOfRangeException.ThrowIfLessThan(startIndex, 0);
+ ArgumentOutOfRangeException.ThrowIfGreaterThan(startIndex + length, Length);
+
if (length == 0)
{
return;
}
- if (length < 0)
- {
- throw new ArgumentOutOfRangeException(nameof(length), "The given length can't be negative.");
- }
-
- if (startIndex < 0)
- {
- throw new ArgumentOutOfRangeException(nameof(startIndex), "The given start index can't be negative.");
- }
-
- if (length > Length - startIndex)
- {
- throw new ArgumentOutOfRangeException(nameof(length), $"The given Span ({startIndex}..{length})length is outside the the represented string.");
- }
-
var beginIndex = startIndex + length;
buffer[beginIndex..bufferPosition].CopyTo(buffer[startIndex..]);
bufferPosition -= length;
diff --git a/tests/LinkDotNet.StringBuilder.UnitTests/ValueStringBuilder.Trim.Tests.cs b/tests/LinkDotNet.StringBuilder.UnitTests/ValueStringBuilder.Trim.Tests.cs
index f616681..0491dfe 100644
--- a/tests/LinkDotNet.StringBuilder.UnitTests/ValueStringBuilder.Trim.Tests.cs
+++ b/tests/LinkDotNet.StringBuilder.UnitTests/ValueStringBuilder.Trim.Tests.cs
@@ -79,4 +79,26 @@ public void GivenString_WhenTrimCharacter_ThenShouldRemoveCharacter()
valueStringBuilder.ToString().ShouldBe("ee");
}
+
+ [Fact]
+ public void GivenString_WhenTrimPrefix_ThenShouldRemoveSpan()
+ {
+ using var valueStringBuilder = new ValueStringBuilder();
+ valueStringBuilder.Append("Hello world");
+
+ valueStringBuilder.TrimPrefix("hell", System.StringComparison.InvariantCultureIgnoreCase);
+
+ valueStringBuilder.ToString().ShouldBe("o world");
+ }
+
+ [Fact]
+ public void GivenString_WhenTrimSuffix_ThenShouldRemoveSpan()
+ {
+ using var valueStringBuilder = new ValueStringBuilder();
+ valueStringBuilder.Append("Hello world");
+
+ valueStringBuilder.TrimPrefix("RlD", System.StringComparison.InvariantCultureIgnoreCase);
+
+ valueStringBuilder.ToString().ShouldBe("Hello wo");
+ }
}
\ No newline at end of file
From e67051ed8501ae88d265baf63f3f0e2bb251a7bf Mon Sep 17 00:00:00 2001
From: Joyless <65855333+Joy-less@users.noreply.github.com>
Date: Thu, 23 Jan 2025 19:49:06 +0000
Subject: [PATCH 2/3] Fix unit tests
---
.../ValueStringBuilder.Trim.Tests.cs | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/tests/LinkDotNet.StringBuilder.UnitTests/ValueStringBuilder.Trim.Tests.cs b/tests/LinkDotNet.StringBuilder.UnitTests/ValueStringBuilder.Trim.Tests.cs
index 0491dfe..8e52ddd 100644
--- a/tests/LinkDotNet.StringBuilder.UnitTests/ValueStringBuilder.Trim.Tests.cs
+++ b/tests/LinkDotNet.StringBuilder.UnitTests/ValueStringBuilder.Trim.Tests.cs
@@ -1,3 +1,5 @@
+using System;
+
namespace LinkDotNet.StringBuilder.UnitTests;
public class ValueStringBuilderTrimTests
@@ -86,7 +88,7 @@ public void GivenString_WhenTrimPrefix_ThenShouldRemoveSpan()
using var valueStringBuilder = new ValueStringBuilder();
valueStringBuilder.Append("Hello world");
- valueStringBuilder.TrimPrefix("hell", System.StringComparison.InvariantCultureIgnoreCase);
+ valueStringBuilder.TrimPrefix("hell", StringComparison.InvariantCultureIgnoreCase);
valueStringBuilder.ToString().ShouldBe("o world");
}
@@ -97,7 +99,7 @@ public void GivenString_WhenTrimSuffix_ThenShouldRemoveSpan()
using var valueStringBuilder = new ValueStringBuilder();
valueStringBuilder.Append("Hello world");
- valueStringBuilder.TrimPrefix("RlD", System.StringComparison.InvariantCultureIgnoreCase);
+ valueStringBuilder.TrimSuffix("RlD", StringComparison.InvariantCultureIgnoreCase);
valueStringBuilder.ToString().ShouldBe("Hello wo");
}
From 45a85ef3a39bbcc2583e0d4de6e9b46fd96b9771 Mon Sep 17 00:00:00 2001
From: Joyless <65855333+Joy-less@users.noreply.github.com>
Date: Thu, 23 Jan 2025 20:50:04 +0000
Subject: [PATCH 3/3] Update CHANGELOG.md
---
CHANGELOG.md | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index d55c727..3017007 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,6 +6,11 @@ All notable changes to **ValueStringBuilder** will be documented in this file. T
## [Unreleased]
+### Added
+
+- Added `TrimPrefix(ReadOnlySpan, StringComparison)` (by yours truly (@Joy-less) in #226)
+- Added `TrimSuffix(ReadOnlySpan, StringComparison)` (also by yours truly (@Joy-less) in #226)
+
## [2.1.0] - 2025-01-14
### Added