Skip to content

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

Description

@koszeggy

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 to use SpanRuneEnumerator or some switch over the length of the span.

Interestingly enough, Rune implements IUtf8SpanParsable<Rune> lately (only explicitly though), but not IParsable<Rune> and ISpanParsable<Rune>.

API Proposal

public struct Rune : IComparable, IComparable<Rune>, IEquatable<Rune>
     , IUtf8SpanFormattable, IUtf8SpanParsable<Rune> // added in .NET 8
+    , IParsable<Rune>, ISpanParsable<Rune> 
{
+    public static Rune Parse(string s, IFormatProvider? provider);
+    public static bool TryParse(string s, IFormatProvider? provider, out Rune result);

+    public static Rune Parse(ReadOnlySpan<char> s, IFormatProvider? provider);
+    public static bool TryParse(ReadOnlySpan<char> s, IFormatProvider? provider, out Rune result);
}

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.)

Metadata

Metadata

Labels

api-approvedAPI was approved in API review, it can be implementedarea-System.Runtimein-prThere is an active PR which will close this issue when it is merged

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions