dotnet / runtime

.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.
https://docs.microsoft.com/dotnet/core/
MIT License
14.98k stars 4.66k forks source link

[API Proposal]: Add [Try]Parse to Rune #60231

Open koszeggy opened 2 years ago

koszeggy commented 2 years ago

Background and motivation

In many aspects Rune is similar to char, it has also the same formatting features, still, it does not support parsing.

As a workaround, one can use the following solution:

private static bool TryParseRune(string s, out Rune value)
{
    if (s == null)
        throw new ArgumentNullException(nameof(s));
    if (Rune.TryGetRuneAt(s, 0, out Rune rune) && rune.Utf16SequenceLength == s.Length)
    {
        value = rune;
        return true;
    }

    value = default;
    return false;
}

But unfortunately TryGetRune has no overloads for ReadOnlySpan<char> so the span version of the workaround should either use enumarator or some switch over the length of the span.

An additional motivation would be to be include the Rune type into the set of IParseable<TSelf> types

API Proposal

public struct Rune : IComparable, IComparable<Rune>, IEquatable<Rune>, ISpanFormattable
+    , IBinaryInteger<Rune>, IMinMaxValue<Rune>, IUnsignedNumber<Rune>
{
+    Rune Parse(string s[, ...]);
+    Rune Parse(ReadOnlySpan<char> s[, ...]);
+    bool TryParse(string s[, ...], out Rune value);
+    bool TryParse(ReadOnlySpan<char> s[, ...], out Rune value);
+    // and the interface implementations
}

API Usage

// Explicit usage example
var r1 = Rune.Parse("πŸ™‚");
bool success = Rune.TryParse("πŸ‘€", out Rune r2);

// Interface usage example
static T Parse<T>(string s) where T : IParseable<T> => T.Parse(s);
var r3 = Parse<Rune>("😎");

Risks

I don't see any. But to be really similar to char maybe a RuneConverter could also be necessary to be able convert to and from string in already existing libraries (eg. XML/JSON serializers, etc.)

dotnet-issue-labeler[bot] commented 2 years ago

I couldn't figure out the best area label to add to this issue. If you have write-permissions please help me learn by adding exactly one area label.

ghost commented 2 years ago

Tagging subscribers to this area: @dotnet/area-system-runtime See info in area-owners.md if you want to be subscribed.

Issue Details
### Background and motivation In many aspects `Rune` is similar to `char`, it has also the same formatting features, still, it does not support parsing. As a workaround, one can use the following solution: ```cs private static bool TryParseRune(string s, out Rune value) { if (s == null) throw new ArgumentNullException(nameof(s)); if (Rune.TryGetRuneAt(s, 0, out Rune rune) && rune.Utf16SequenceLength == s.Length) { value = rune; return true; } value = default; return false; } ``` But unfortunately `TryGetRune` has no overloads for `ReadOnlySpan` so the span version of the workaround should either use enumarator or some switch over the length of the span. An additional motivation would be to be include the `Rune` type into the set of `IParseable` types ### API Proposal ```diff public struct Rune : IComparable, IComparable, IEquatable, ISpanFormattable + , IBinaryInteger, IMinMaxValue, IUnsignedNumber { + Rune Parse(string s[, ...]); + Rune Parse(ReadOnlySpan s[, ...]); + bool TryParse(string s[, ...], out Rune value); + bool TryParse(ReadOnlySpan s[, ...], out Rune value); + // and the interface implementations } ``` ### API Usage ```C# // Explicit usage example var r1 = Rune.Parse("πŸ™‚"); bool success = Rune.TryParse("πŸ‘€", out Rune r2); // Interface usage example static T Parse(string s) where T : IParseable => T.Parse(s); var r3 = Parse("😎"); ``` ### Risks I don't see any. But to be really similar to `char` maybe a `RuneConverter` could also be necessary to be able convert to and from string in already existing libraries (eg. XML/JSON serializers, etc.)
Author: koszeggy
Assignees: -
Labels: `api-suggestion`, `area-System.Runtime`, `untriaged`
Milestone: -