DotNext by .NET Foundation and Contributors

<PackageReference Include="DotNext" Version="4.4.0" />

 MemoryTemplate

public static class MemoryTemplate
Represents various extensions for MemoryTemplate<T> type.
using System; using System.Buffers; using System.Collections.Generic; using System.IO; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Text; using System.Threading; using System.Threading.Tasks; namespace DotNext.Buffers { [System.Runtime.CompilerServices.NullableContext(1)] [System.Runtime.CompilerServices.Nullable(0)] public static class MemoryTemplate { [StructLayout(LayoutKind.Auto)] private readonly struct StringBuilderRenderer : IReadOnlySpanConsumer<char>, ISupplier<ReadOnlyMemory<char>, CancellationToken, ValueTask>, IConsumer<int> { private readonly IReadOnlyList<string> replacement; private readonly StringBuilder output; internal StringBuilderRenderer(StringBuilder output, IReadOnlyList<string> replacement) { this.output = output; this.replacement = replacement; } void IReadOnlySpanConsumer<char>.Invoke(ReadOnlySpan<char> input) { output.Append(input); } void IConsumer<int>.Invoke(int index) { output.Append(replacement[index]); } } [StructLayout(LayoutKind.Auto)] private readonly struct CharBufferRenderer : IReadOnlySpanConsumer<char>, ISupplier<ReadOnlyMemory<char>, CancellationToken, ValueTask>, IConsumer<int> { private readonly IReadOnlyList<string> replacement; private readonly IBufferWriter<char> output; internal CharBufferRenderer(IBufferWriter<char> output, IReadOnlyList<string> replacement) { this.output = output; this.replacement = replacement; } void IReadOnlySpanConsumer<char>.Invoke(ReadOnlySpan<char> input) { output.Write(input); } void IConsumer<int>.Invoke(int index) { output.Write(replacement[index]); } } [StructLayout(LayoutKind.Auto)] private readonly struct TextRenderer : IReadOnlySpanConsumer<char>, ISupplier<ReadOnlyMemory<char>, CancellationToken, ValueTask>, IConsumer<int> { private readonly IReadOnlyList<string> replacement; private readonly TextWriter output; internal TextRenderer(TextWriter output, IReadOnlyList<string> replacement) { this.output = output; this.replacement = replacement; } void IReadOnlySpanConsumer<char>.Invoke(ReadOnlySpan<char> input) { output.Write(input); } void IConsumer<int>.Invoke(int index) { output.Write(replacement[index]); } } public static void Render([In] [IsReadOnly] [System.Runtime.CompilerServices.Nullable(0)] ref MemoryTemplate<char> template, StringBuilder output, params string[] replacement) { template.Render(new StringBuilderRenderer(output, replacement)); } public static string Render([In] [IsReadOnly] [System.Runtime.CompilerServices.Nullable(0)] ref MemoryTemplate<char> template, params string[] replacement) { using (PooledArrayBufferWriter<char> pooledArrayBufferWriter = new PooledArrayBufferWriter<char> { Capacity = template.Value.Length }) { template.Render(new CharBufferRenderer(pooledArrayBufferWriter, replacement)); return new string(pooledArrayBufferWriter.WrittenArray); } } public static void Render([In] [IsReadOnly] [System.Runtime.CompilerServices.Nullable(0)] ref MemoryTemplate<char> template, TextWriter output, params string[] replacement) { template.Render(new TextRenderer(output, replacement)); } } }