diff --git a/CHANGELOG.md b/CHANGELOG.md
index abb2f7a..478943c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,6 +6,10 @@ All notable changes to **ValueStringBuilder** will be documented in this file. T
## [Unreleased]
+### Added
+
+- Added custom enumerator to `ValueStringBuilder` so it can be used in `foreach` loops
+
## [1.17.0] - 2023-04-13
### Added
diff --git a/src/LinkDotNet.StringBuilder/ValueStringBuilder.Enumerator.cs b/src/LinkDotNet.StringBuilder/ValueStringBuilder.Enumerator.cs
new file mode 100644
index 0000000..08b829f
--- /dev/null
+++ b/src/LinkDotNet.StringBuilder/ValueStringBuilder.Enumerator.cs
@@ -0,0 +1,48 @@
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+namespace LinkDotNet.StringBuilder;
+
+public ref partial struct ValueStringBuilder
+{
+ public readonly Enumerator GetEnumerator() => new(buffer[..bufferPosition]);
+
+ /// Enumerates the elements of a .
+ [StructLayout(LayoutKind.Auto)]
+ public ref struct Enumerator
+ {
+ private readonly Span span;
+ private int index;
+
+ /// Initializes a new instance of the struct.
+ /// The span to enumerate.
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ internal Enumerator(Span span)
+ {
+ this.span = span;
+ index = -1;
+ }
+
+ /// Gets the element at the current position of the enumerator.
+ public ref char Current
+ {
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ get => ref span[index];
+ }
+
+ /// Advances the enumerator to the next element of the span.
+ /// True if the enumerator was successfully advanced to the next element; false if the enumerator has passed the end of the span.
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public bool MoveNext()
+ {
+ var nextIndex = index + 1;
+ if (nextIndex < span.Length)
+ {
+ index = nextIndex;
+ return true;
+ }
+
+ return false;
+ }
+ }
+}
\ No newline at end of file
diff --git a/stylecop.analyzers.ruleset b/stylecop.analyzers.ruleset
index 3c61a4c..660192c 100644
--- a/stylecop.analyzers.ruleset
+++ b/stylecop.analyzers.ruleset
@@ -9,6 +9,8 @@
+
+
diff --git a/tests/LinkDotNet.StringBuilder.UnitTests/ValueStringBuilderTests.cs b/tests/LinkDotNet.StringBuilder.UnitTests/ValueStringBuilderTests.cs
index 655a296..44d8528 100644
--- a/tests/LinkDotNet.StringBuilder.UnitTests/ValueStringBuilderTests.cs
+++ b/tests/LinkDotNet.StringBuilder.UnitTests/ValueStringBuilderTests.cs
@@ -489,4 +489,18 @@ public void GivenAString_WhenCallingToStringWithRange_ThenShouldReturnSubstring(
builder.ToString(1..4).Should().Be("ell");
}
+
+ [Fact]
+ public void GivenAString_WhenEnumerating_ThenShouldReturnCharacters()
+ {
+ using var builder = new ValueStringBuilder("Hello World");
+ var output = string.Empty;
+
+ foreach (var c in builder)
+ {
+ output += c;
+ }
+
+ output.Should().Be("Hello World");
+ }
}
\ No newline at end of file