-
Notifications
You must be signed in to change notification settings - Fork 5.2k
Closed
Labels
api-approvedAPI was approved in API review, it can be implementedAPI was approved in API review, it can be implementedarea-System.Buffers
Milestone
Description
Background and motivation
In .NET 6, as part of rolling out the improved support for string interpolation, we added some TryWrite extension methods to MemoryExtensions that enable interpolating directly into a Span<char>, e.g.
Span<char> span = ...;
bool wrote = span.TryWrite($"The current day/time is {DateTime.Now}", out int charsWritten);We should consider enabling the same capability for writing UTF8 into a Span<byte>.
API Proposal
namespace System
{
public static class MemoryExtensions
{
+ public static bool TryWrite(this Span<byte> utf8Destination, [InterpolatedStringHandlerArgument("destination")] ref TryWriteUtf8InterpolatedStringHandler handler, out int bytesWritten);
+ public static bool TryWrite(this Span<byte> utf8Destination, IFormatProvider? provider, [InterpolatedStringHandlerArgument("destination", "provider")] ref TryWriteUtf8InterpolatedStringHandler handler, out int bytesWritten);
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ [InterpolatedStringHandlerAttribute]
+ public ref struct TryWriteUtf8InterpolatedStringHandler
+ {
+ public TryWriteInterpolatedStringHandler(int literalLength, int formattedCount, Span<byte> utf8Destination, out bool shouldAppend);
+ public TryWriteInterpolatedStringHandler(int literalLength, int formattedCount, Span<byte> utf8Destination, IFormatProvider? provider, out bool shouldAppend);
+ public bool AppendLiteral(string value);
+ // public bool AppendLiteral(ReadOnlySpan<byte> value); // if the C# compiler supports interpolation with u8 literals
+ public bool AppendFormatted(scoped ReadOnlySpan<char> value);
+ public bool AppendFormatted(scoped ReadOnlySpan<char> value, int alignment = 0, string? format = null);
+ public bool AppendFormatted(scoped ReadOnlySpan<byte> utf8Value);
+ public bool AppendFormatted(scoped ReadOnlySpan<byte> utf8Value, int alignment = 0, string? format = null);
+ public bool AppendFormatted<T>(T value);
+ public bool AppendFormatted<T>(T value, string? format);
+ public bool AppendFormatted<T>(T value, int alignment);
+ public bool AppendFormatted<T>(T value, int alignment, string? format);
+ public bool AppendFormatted(object? value, int alignment = 0, string? format = null);
+ public bool AppendFormatted(string? value);
+ public bool AppendFormatted(string? value, int alignment = 0, string? format = null);
}
}This is essentially the exact same design as for MemoryExtensions.TryWrite, with a few specific differences:
- The
TryWritemethods take aSpan<byte>instead of aSpan<char>. - In addition to
ReadOnlySpan<char>-basedAppendFormattedmethods, there are alsoReadOnlySpan<byte>-basedAppendFormattedmethods, the latter of which is expected to be UTF8 data, like a u8 literal. TheReadOnlySpan<byte>data would be memcpy'd into the destination, whereas theReadOnlySpan<char>data would beEncoding.UTF8-encoded into the destination. - The implementation of
Append<T>will check forIUtf8SpanFormattablebefore it checks forISpanFormattable, prefering to use a type's built-in UTF8 formatting support if supplied.
Also note that the AppendLiteral method takes a string value, as that's what's supported by the C# language. If C# were to ever support u8 literals in string interpolation, we could add an appropriate AppendLiteral(ReadOnlySpan<byte> utf8Value) overload.
API Usage
Span<byte> utf8 = ...;
bool wrote = utf8.TryWrite($"The current day/time is {DateTime.Now}", out int bytesWritten);Alternative Designs
No response
Risks
No response
Zintom, DaZombieKiller, sveinungf, PaulusParssinen, DamianEdwards and 3 more
Metadata
Metadata
Assignees
Labels
api-approvedAPI was approved in API review, it can be implementedAPI was approved in API review, it can be implementedarea-System.Buffers