diff --git a/Inspectron.Epson.Tests/Telemetry/InsinMessageFormatterTests.cs b/Inspectron.Epson.Tests/Telemetry/InsinMessageFormatterTests.cs new file mode 100644 index 0000000..2645ca4 --- /dev/null +++ b/Inspectron.Epson.Tests/Telemetry/InsinMessageFormatterTests.cs @@ -0,0 +1,52 @@ +using Inspectron.Epson.PrintServer.Telemetry; + +namespace Inspectron.Epson.Tests.Telemetry; + +public class InsinMessageFormatterTests +{ + [Fact] + public void Format_single_pair_no_spaces() + { + var result = InsinMessageFormatter.Format(("printer", "192.168.1.10")); + Assert.Equal("printer=192.168.1.10", result); + } + + [Fact] + public void Format_multiple_pairs_joined_by_space() + { + var result = InsinMessageFormatter.Format( + ("printer", "192.168.1.10"), + ("jobId", "42")); + Assert.Equal("printer=192.168.1.10 jobId=42", result); + } + + [Fact] + public void Format_quotes_value_containing_space() + { + var result = InsinMessageFormatter.Format(("error", "paper end detected")); + Assert.Equal("error=\"paper end detected\"", result); + } + + [Fact] + public void Format_escapes_embedded_double_quote() + { + var result = InsinMessageFormatter.Format(("error", "he said \"nope\"")); + Assert.Equal("error=\"he said \\\"nope\\\"\"", result); + } + + [Fact] + public void Format_treats_null_or_empty_value_as_empty_string() + { + var result = InsinMessageFormatter.Format(("model", (string?)null), ("name", "")); + Assert.Equal("model= name=", result); + } + + [Fact] + public void Format_omits_pairs_with_null_or_empty_key() + { + var result = InsinMessageFormatter.Format( + ("", "ignored"), + ("printer", "192.168.1.10")); + Assert.Equal("printer=192.168.1.10", result); + } +} diff --git a/Inspectron.Epson/PrintServer/Telemetry/InsinMessageFormatter.cs b/Inspectron.Epson/PrintServer/Telemetry/InsinMessageFormatter.cs new file mode 100644 index 0000000..2c1770c --- /dev/null +++ b/Inspectron.Epson/PrintServer/Telemetry/InsinMessageFormatter.cs @@ -0,0 +1,26 @@ +using System.Text; + +namespace Inspectron.Epson.PrintServer.Telemetry; + +public static class InsinMessageFormatter +{ + public static string Format(params (string Key, string? Value)[] pairs) + { + var sb = new StringBuilder(); + foreach (var (key, value) in pairs) + { + if (string.IsNullOrEmpty(key)) continue; + if (sb.Length > 0) sb.Append(' '); + sb.Append(key).Append('=').Append(FormatValue(value)); + } + return sb.ToString(); + } + + private static string FormatValue(string? value) + { + if (string.IsNullOrEmpty(value)) return string.Empty; + if (value.IndexOf(' ') < 0 && value.IndexOf('"') < 0) return value; + var escaped = value.Replace("\\", "\\\\").Replace("\"", "\\\""); + return $"\"{escaped}\""; + } +}