using System.Text; namespace Nbt; public sealed class IndentedWriter(TextWriter baseWriter, string indent, bool leaveOpen = false) : TextWriter { private readonly TextWriter baseWriter = baseWriter; private readonly string indent = indent; private readonly bool leaveOpen = leaveOpen; private uint depth = 0u; public IndentedWriter(StringBuilder sb, string indent) : this(new StringWriter(sb), indent) { } public override Encoding Encoding => baseWriter.Encoding; public IndentationLevel NewIndentationLevel() => new(this); public override void Write(char value) => baseWriter.Write(value); public override void WriteLine() { baseWriter.WriteLine(); for (var i = 0u; i < depth; i++) { baseWriter.Write(indent); } } public override async Task WriteAsync(char value) => await baseWriter.WriteAsync(value); public override async Task WriteLineAsync() { await baseWriter.WriteLineAsync(); for (var i = 0u; i < depth; i++) { await baseWriter.WriteAsync(indent); } } protected override void Dispose(bool disposing) { try { if (disposing) { if (!leaveOpen) { baseWriter.Dispose(); } } } finally { base.Dispose(disposing); } } public override async ValueTask DisposeAsync() { try { if (!leaveOpen) { await baseWriter.DisposeAsync(); } } finally { await base.DisposeAsync(); } } public readonly struct IndentationLevel : IDisposable { private readonly IndentedWriter writer; public IndentationLevel(IndentedWriter writer) { this.writer = writer; writer.depth++; } public void Dispose() { writer.depth--; } } }