Skip to content

Commit a02c43d

Browse files
authored
Merge pull request #226 from Joy-less/add-trim-prefix-and-trim-suffix
Add TrimPrefix and TrimSuffix
2 parents 8fe75ac + 45a85ef commit a02c43d

File tree

4 files changed

+77
-31
lines changed

4 files changed

+77
-31
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@ All notable changes to **ValueStringBuilder** will be documented in this file. T
66

77
## [Unreleased]
88

9+
### Added
10+
11+
- Added `TrimPrefix(ReadOnlySpan<char>, StringComparison)` (by yours truly (@Joy-less) in #226)
12+
- Added `TrimSuffix(ReadOnlySpan<char>, StringComparison)` (also by yours truly (@Joy-less) in #226)
13+
914
## [2.1.0] - 2025-01-14
1015

1116
### Added

src/LinkDotNet.StringBuilder/ValueStringBuilder.Trim.cs

Lines changed: 44 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ namespace LinkDotNet.StringBuilder;
55
public ref partial struct ValueStringBuilder
66
{
77
/// <summary>
8-
/// Removes a set of whitespace characters from the beginning and ending of this string.
8+
/// Removes all whitespace characters from the start and end of this builder.
99
/// </summary>
1010
[MethodImpl(MethodImplOptions.AggressiveInlining)]
1111
public void Trim()
@@ -33,22 +33,22 @@ public void Trim()
3333
}
3434

3535
/// <summary>
36-
/// Removes the specified character from the beginning and end of this string.
36+
/// Removes all occurrences of the specified character from the start and end of this builder.
3737
/// </summary>
38-
/// <param name="c">The character to remove.</param>
38+
/// <param name="value">The character to remove.</param>
3939
[MethodImpl(MethodImplOptions.AggressiveInlining)]
40-
public void Trim(char c)
40+
public void Trim(char value)
4141
{
4242
// Remove character from the beginning
4343
var start = 0;
44-
while (start < bufferPosition && buffer[start] == c)
44+
while (start < bufferPosition && buffer[start] == value)
4545
{
4646
start++;
4747
}
4848

4949
// Remove character from the end
5050
var end = bufferPosition - 1;
51-
while (end >= start && buffer[end] == c)
51+
while (end >= start && buffer[end] == value)
5252
{
5353
end--;
5454
}
@@ -62,7 +62,7 @@ public void Trim(char c)
6262
}
6363

6464
/// <summary>
65-
/// Removes a set of whitespace characters from the beginning of this string.
65+
/// Removes all whitespace characters from the start of this builder.
6666
/// </summary>
6767
[MethodImpl(MethodImplOptions.AggressiveInlining)]
6868
public void TrimStart()
@@ -82,14 +82,14 @@ public void TrimStart()
8282
}
8383

8484
/// <summary>
85-
/// Removes the specified character from the beginning of this string.
85+
/// Removes all occurrences of the specified character from the start of this builder.
8686
/// </summary>
87-
/// <param name="c">The character to remove.</param>
87+
/// <param name="value">The character to remove.</param>
8888
[MethodImpl(MethodImplOptions.AggressiveInlining)]
89-
public void TrimStart(char c)
89+
public void TrimStart(char value)
9090
{
9191
var start = 0;
92-
while (start < bufferPosition && buffer[start] == c)
92+
while (start < bufferPosition && buffer[start] == value)
9393
{
9494
start++;
9595
}
@@ -103,7 +103,7 @@ public void TrimStart(char c)
103103
}
104104

105105
/// <summary>
106-
/// Removes a set of whitespace characters from the ending of this string.
106+
/// Removes all whitespace characters from the end of this builder.
107107
/// </summary>
108108
[MethodImpl(MethodImplOptions.AggressiveInlining)]
109109
public void TrimEnd()
@@ -118,18 +118,46 @@ public void TrimEnd()
118118
}
119119

120120
/// <summary>
121-
/// Removes the specified character from the end of this string.
121+
/// Removes all occurrences of the specified character from the end of this builder.
122122
/// </summary>
123-
/// <param name="c">The character to remove.</param>
123+
/// <param name="value">The character to remove.</param>
124124
[MethodImpl(MethodImplOptions.AggressiveInlining)]
125-
public void TrimEnd(char c)
125+
public void TrimEnd(char value)
126126
{
127127
var end = bufferPosition - 1;
128-
while (end >= 0 && buffer[end] == c)
128+
while (end >= 0 && buffer[end] == value)
129129
{
130130
end--;
131131
}
132132

133133
bufferPosition = end + 1;
134134
}
135+
136+
/// <summary>
137+
/// Removes the specified sequence of characters from the start of this builder.
138+
/// </summary>
139+
/// <param name="value">The sequence of characters to remove.</param>
140+
/// <param name="comparisonType">The way to compare the sequences of characters.</param>
141+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
142+
public void TrimPrefix(ReadOnlySpan<char> value, StringComparison comparisonType = StringComparison.Ordinal)
143+
{
144+
if (AsSpan().StartsWith(value, comparisonType))
145+
{
146+
Remove(0, value.Length);
147+
}
148+
}
149+
150+
/// <summary>
151+
/// Removes the specified sequence of characters from the end of this builder.
152+
/// </summary>
153+
/// <param name="value">The sequence of characters to remove.</param>
154+
/// <param name="comparisonType">The way to compare the sequences of characters.</param>
155+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
156+
public void TrimSuffix(ReadOnlySpan<char> value, StringComparison comparisonType = StringComparison.Ordinal)
157+
{
158+
if (AsSpan().EndsWith(value, comparisonType))
159+
{
160+
Remove(Length - value.Length, value.Length);
161+
}
162+
}
135163
}

src/LinkDotNet.StringBuilder/ValueStringBuilder.cs

Lines changed: 4 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -199,26 +199,15 @@ public void EnsureCapacity(int newCapacity)
199199
[MethodImpl(MethodImplOptions.AggressiveInlining)]
200200
public void Remove(int startIndex, int length)
201201
{
202+
ArgumentOutOfRangeException.ThrowIfLessThan(length, 0);
203+
ArgumentOutOfRangeException.ThrowIfLessThan(startIndex, 0);
204+
ArgumentOutOfRangeException.ThrowIfGreaterThan(startIndex + length, Length);
205+
202206
if (length == 0)
203207
{
204208
return;
205209
}
206210

207-
if (length < 0)
208-
{
209-
throw new ArgumentOutOfRangeException(nameof(length), "The given length can't be negative.");
210-
}
211-
212-
if (startIndex < 0)
213-
{
214-
throw new ArgumentOutOfRangeException(nameof(startIndex), "The given start index can't be negative.");
215-
}
216-
217-
if (length > Length - startIndex)
218-
{
219-
throw new ArgumentOutOfRangeException(nameof(length), $"The given Span ({startIndex}..{length})length is outside the the represented string.");
220-
}
221-
222211
var beginIndex = startIndex + length;
223212
buffer[beginIndex..bufferPosition].CopyTo(buffer[startIndex..]);
224213
bufferPosition -= length;

tests/LinkDotNet.StringBuilder.UnitTests/ValueStringBuilder.Trim.Tests.cs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
using System;
2+
13
namespace LinkDotNet.StringBuilder.UnitTests;
24

35
public class ValueStringBuilderTrimTests
@@ -79,4 +81,26 @@ public void GivenString_WhenTrimCharacter_ThenShouldRemoveCharacter()
7981

8082
valueStringBuilder.ToString().ShouldBe("ee");
8183
}
84+
85+
[Fact]
86+
public void GivenString_WhenTrimPrefix_ThenShouldRemoveSpan()
87+
{
88+
using var valueStringBuilder = new ValueStringBuilder();
89+
valueStringBuilder.Append("Hello world");
90+
91+
valueStringBuilder.TrimPrefix("hell", StringComparison.InvariantCultureIgnoreCase);
92+
93+
valueStringBuilder.ToString().ShouldBe("o world");
94+
}
95+
96+
[Fact]
97+
public void GivenString_WhenTrimSuffix_ThenShouldRemoveSpan()
98+
{
99+
using var valueStringBuilder = new ValueStringBuilder();
100+
valueStringBuilder.Append("Hello world");
101+
102+
valueStringBuilder.TrimSuffix("RlD", StringComparison.InvariantCultureIgnoreCase);
103+
104+
valueStringBuilder.ToString().ShouldBe("Hello wo");
105+
}
82106
}

0 commit comments

Comments
 (0)