diff --git a/src/Superpower/Model/TextSpan.cs b/src/Superpower/Model/TextSpan.cs index f8c8f5c..c8f0358 100644 --- a/src/Superpower/Model/TextSpan.cs +++ b/src/Superpower/Model/TextSpan.cs @@ -270,5 +270,52 @@ public bool EqualsValueIgnoreCase(string otherValue) } return true; } + + /// + /// Gets the character at the specified index in the text span. + /// + /// + /// The zero-based index of the character to get. + /// + /// + /// The character at the specified index in the text span. + /// + public char this[int index] + { + get + { + this.EnsureHasValue(); +#if CHECKED + if ((uint)index >= (uint)Length) + throw new ArgumentOutOfRangeException(nameof(index), index, "Index exceeds the source span's length."); +#endif + return Source![Position.Absolute + index]; + } + } + + /// + /// Forms a slice out of the current text span starting at the specified index. + /// + /// + /// The index at which to begin the slice. + /// + /// + /// An text span that consists of all elements of the current array segment from to the end of the text span. + /// + public TextSpan Slice(int index) + { + return Skip(index); + } + + /// + /// Forms a slice of the specified length out of the current text span starting at the specified index. + /// + /// The index at which to begin the slice. + /// The desired length of the slice. + /// An text span of elements starting at . + public TextSpan Slice(int index, int count) + { + return Skip(index).First(count); + } } } \ No newline at end of file diff --git a/test/Superpower.Tests/StringSpanTests.cs b/test/Superpower.Tests/StringSpanTests.cs index f5e87a3..71c2bf0 100644 --- a/test/Superpower.Tests/StringSpanTests.cs +++ b/test/Superpower.Tests/StringSpanTests.cs @@ -90,5 +90,38 @@ public void ASpanIsNotEqualToADifferentString(string str, int offset, int length var span = new TextSpan(str, new Position(offset, 1, offset + 1), length); Assert.False(span.EqualsValue(value)); } + + [Theory] + [InlineData("Hello", 0, 5)] + [InlineData("Hello", 0, 3)] + [InlineData("Hello", 1, 3)] + public void SliceWithLengthExtractsCorrectCharacters(string input, int index, int end) + { + var inputSpan = new TextSpan(input, new Position(0, 1, 1), input.Length); + var slice = inputSpan[index..end]; + Assert.Equal(expected: input[index..end], actual: slice.ToStringValue()); + } + + [Theory] + [InlineData("Hello", 0)] + [InlineData("Hello", 2)] + [InlineData("Hello", 5)] + public void SliceWithoutLengthExtractsCorrectCharacters(string input, int index) + { + var inputSpan = new TextSpan(input, new Position(0, 1, 1), input.Length); + var slice = inputSpan[index..]; + Assert.Equal(expected: input[index..], actual: slice.ToStringValue()); + } + + [Theory] + [InlineData("Hello", 0)] + [InlineData("Hello", 2)] + [InlineData("Hello", 4)] + public void IndexerExtractsCorrectCharacter(string input, int index) + { + var inputSpan = new TextSpan(input, new Position(0, 1, 1), input.Length); + var ch = inputSpan[index]; + Assert.Equal(expected: input[index], actual: ch); + } } }