From c09aad264fd5d272bfa21c4b459f321cb04a5330 Mon Sep 17 00:00:00 2001 From: Mike Christiansen Date: Sat, 31 Aug 2024 11:25:06 -0400 Subject: [PATCH 1/2] Add slice support for TextSpan --- src/Superpower/Model/TextSpan.cs | 48 ++++++++++++++++++++++++ test/Superpower.Tests/StringSpanTests.cs | 33 ++++++++++++++++ 2 files changed, 81 insertions(+) diff --git a/src/Superpower/Model/TextSpan.cs b/src/Superpower/Model/TextSpan.cs index f8c8f5c..5f2c299 100644 --- a/src/Superpower/Model/TextSpan.cs +++ b/src/Superpower/Model/TextSpan.cs @@ -270,5 +270,53 @@ 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); + } } } From 116c4e0fc7bd40bf8b15d99661ae3820dd2c2f4e Mon Sep 17 00:00:00 2001 From: Mike Christiansen Date: Mon, 2 Sep 2024 20:02:53 -0400 Subject: [PATCH 2/2] Remove extra newline --- src/Superpower/Model/TextSpan.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Superpower/Model/TextSpan.cs b/src/Superpower/Model/TextSpan.cs index 5f2c299..c8f0358 100644 --- a/src/Superpower/Model/TextSpan.cs +++ b/src/Superpower/Model/TextSpan.cs @@ -271,7 +271,6 @@ public bool EqualsValueIgnoreCase(string otherValue) return true; } - /// /// Gets the character at the specified index in the text span. ///