Closed binarycow closed 2 months ago
Thanks for the PR! Are there any places in the Superpower codebase, or typical usage patterns, where slicing is useful with TextSpan
? (Just a standard consideration when adding any feature, to keep the library nice and compact.) Thanks!
Are there any places in the Superpower codebase, or typical usage patterns, where slicing is useful with TextSpan?
Well...
textSpan.Skip(10)
, you could use textSpan[10..]
textSpan.First(textSpan.Length - 10)
, you could use textSpan[..^10]
textSpan.First(10)
, you could use textSpan.Slice(0, 10)
. You can't use the range operator here, because the second argument to the range operator is the index from the end. That makes this particular usage not so great, as you can just call First
, and not have to have the 0
operator.Primarily, it should be supported because other similar types* support slicing, such as ArraySegment<T>
, ReadOnlySpan<T>
, Span<T>
, Memory<T>
, ReadOnlyMemory<T>
, ReadOnlySequence<T>
. Even ImmutableArray<T>
supports slicing.
One benefit to meeting the slicing "interface" (it's duck-typed, not a true interface), aside from using the range operator (..
) is providing an API that is familiar to developers who are not used to dealing with TextSpan
. They don't need to figure out that they want First
and Skip
. They don't need to read the xmldocs to see what the parameters mean. It's Slice
, just like every other slicable type.
My specific use case:
I "reached for" the non-existant slice capability in a parser I was writing. This language has three different kinds of strings (unquoted, single-quoted, double-quoted). Those strings can be appended. Double quoted strings support escaping and trimming (the trimming is much like C#'s raw strings).
I found it easiest to, in my parsing method, just accept the token values - quotes and all - and then pass the final result to another method that would handle concatenation, escaping, trimming, etc. That method would use the quotes to know how to handle that portion of the string. It would then strip the quotes off, with a simple span[1..^1]
. Instead, I have to do this: span.First(span.Length - 1).Skip(1)
.
* Notably, StringSegment
in Microsoft.Extensions.Primitives
(the most direct comparison to TextSpan
) does not support slicing, but this is probably because it's fairly new, is trying to match the string
API (so it uses Substring
instead of Slice
), and it is not special-cased by the compiler, like string
is (for string
, the compiler will use Substring
instead of Slice
, and for arrays, the compiler will use System.Runtime.CompilerServices.RuntimeHelpers.GetSubArray
instead of Slice
). I have a feeling that eventually, especially if StringSegment
catches on as a non-ref-struct counterpart to ReadOnlySpan<char>
, they'll either special case StringSegment
, or support SubString
in addition to Slice
.
Thanks @binarycow 👍
This PR adds to
TextSpan
, an indexer, and support for the range operator (..
)Exactly how well this is supported depends on the target framework of the application that uses this library:
Slice
methods work as expected.