using System; using System.Diagnostics; using System.Text; internal sealed class StatusReporter { private int _dotCounter = 0; private string _lastMessage = string.Empty; private DateTime _lastWriteTime = DateTime.MinValue; public void Show(string message, bool withDots = false) { if (withDots) { _dotCounter++; message = $"{message}{Dots()}"; } Write(message, newline: false); } public string Dots() { var dots = (_dotCounter % 3) + 1; return new string('.', dots); } public void ShowLine(string message) { Write(message, newline: true); } private void Write(string message, bool newline) { if (_lastMessage == message && !newline) return; var now = DateTime.UtcNow; if (!newline && (now - _lastWriteTime).TotalMilliseconds < 200) { return; } _lastWriteTime = now; var pad = string.Empty; _lastMessage = message; var output = $"\r\u001b[K{message}{pad}"; if (newline) { Console.Error.WriteLine(output); _lastMessage = string.Empty; } else { Console.Error.Write(output); } } public static string FormatDuration(TimeSpan elapsed) { if (elapsed.TotalMinutes >= 1) { return $"{(int)elapsed.TotalMinutes}m {elapsed.Seconds}s"; } return $"{elapsed.Seconds}s"; } }