using System; using System.Diagnostics.CodeAnalysis; using System.Text; using StardewModdingAPI.Web.Framework.LogParsing.Models; namespace StardewModdingAPI.Web.Framework.LogParsing { /// Handles constructing log message instances with minimal memory allocation. internal class LogMessageBuilder { /********* ** Fields *********/ /// The local time when the next log was posted. public string? Time { get; set; } /// The log level for the next log message. public LogLevel Level { get; set; } /// The screen ID in split-screen mode. public int ScreenId { get; set; } /// The mod name for the next log message. public string? Mod { get; set; } /// The text for the next log message. private readonly StringBuilder Text = new(); /********* ** Accessors *********/ /// Whether the next log message has been started. [MemberNotNullWhen(true, nameof(LogMessageBuilder.Time), nameof(LogMessageBuilder.Mod))] public bool Started { get; private set; } /********* ** Public methods *********/ /// Start accumulating values for a new log message. /// The local time when the log was posted. /// The log level. /// The screen ID in split-screen mode. /// The mod name. /// The initial log text. /// A log message is already started; call before starting a new message. public void Start(string time, LogLevel level, int screenId, string mod, string text) { if (this.Started) throw new InvalidOperationException("Can't start new message, previous log message isn't done yet."); this.Started = true; this.Time = time; this.Level = level; this.ScreenId = screenId; this.Mod = mod; this.Text.Append(text); } /// Add a new line to the next log message being built. /// The line to add. /// A log message hasn't been started yet. public void AddLine(string text) { if (!this.Started) throw new InvalidOperationException("Can't add text, no log message started yet."); this.Text.Append("\n"); this.Text.Append(text); } /// Get a log message for the accumulated values. public LogMessage? Build() { if (!this.Started) return null; return new LogMessage( time: this.Time, level: this.Level, screenId: this.ScreenId, mod: this.Mod, text: this.Text.ToString() ); } /// Reset to start a new log message. public void Clear() { this.Started = false; this.Text.Clear(); } } }