using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace PCL.Core.Utils; public class ArgumentsBuilder { private readonly List _args = []; private enum ArgumentStyle { Flag, /// /// Concated by '=' symbol. /// Equals, /// /// Concated by space. /// Space } private readonly struct Argument(string key, string? value, ArgumentStyle style) { public readonly string Key = key ?? throw new ArgumentNullException(nameof(key)); public readonly string? Value = value; public readonly ArgumentStyle Style = style; } /// /// 添加键值对参数(自动处理空格转义) /// /// 参数名(不带前缀) /// 参数值 public ArgumentsBuilder Add(string key, string value) { if (key is null) throw new NullReferenceException(nameof(key)); if (value is null) throw new NullReferenceException(nameof(value)); _args.Add(new Argument(key, _HandleValue(value), ArgumentStyle.Equals)); return this; } /// /// 添加由空格连接到键值对参数(自动处理空格转义) /// /// 参数名(不带前缀) /// 参数值 public ArgumentsBuilder AddWithSpace(string key, string value) { if (key is null) throw new NullReferenceException(nameof(key)); if (value is null) throw new NullReferenceException(nameof(value)); _args.Add(new Argument(key, _HandleValue(value), ArgumentStyle.Space)); return this; } /// /// 添加标志参数(无值参数) /// /// 标志名(不带前缀) public ArgumentsBuilder AddFlag(string flag) { if (flag is null) throw new NullReferenceException(nameof(flag)); _args.Add(new Argument(flag, null, ArgumentStyle.Flag)); return this; } /// /// 条件添加参数(仅当condition为true时添加) /// public ArgumentsBuilder AddIf(bool condition, string key, string value) { if (condition) Add(key, value); return this; } /// /// 条件添加由空格连接的参数(仅当condition为true时添加) /// public ArgumentsBuilder AddWithSpaceIf(bool condition, string key, string value) { if (condition) AddWithSpace(key, value); return this; } /// /// 条件添加标志(仅当condition为true时添加) /// public ArgumentsBuilder AddFlagIf(bool condition, string flag) { if (condition) AddFlag(flag); return this; } public enum PrefixStyle { /// /// 自动(单字符用-,多字符用--) /// Auto, /// /// 强制单横线 /// SingleLine, /// /// 强制双横线 /// DoubleLine } /// /// 构建参数字符串 /// /// 前缀样式 public string GetResult(PrefixStyle prefixStyle = 0) { var sb = new StringBuilder(); foreach (var arg in _args) { if (sb.Length > 0) sb.Append(' '); // 添加前缀 switch (prefixStyle) { case PrefixStyle.SingleLine: // 强制单横线 sb.Append('-').Append(arg.Key); break; case PrefixStyle.DoubleLine: // 强制双横线 sb.Append("--").Append(arg.Key); break; default: // 自动判断 sb.Append(arg.Key.Length == 1 ? "-" : "--").Append(arg.Key); break; } // 添加值(如果有) if (arg.Value is not null) { switch (arg.Style) { case ArgumentStyle.Equals: sb.Append('=') .Append(arg.Value); break; case ArgumentStyle.Space: sb.Append(' ') .Append(arg.Value); break; } } } return sb.ToString(); } public override string ToString() { return GetResult(); } /// /// 清空所有参数 /// public void Clear() => _args.Clear(); private static readonly char[] _CharNeedToQute = [' ', '=', '|', '"']; // 转义包含空格的值(用双引号包裹) private static string _HandleValue(string value) { if (string.IsNullOrWhiteSpace(value)) return $"\"{value}\""; return value.All(x => !_CharNeedToQute.Contains(x)) ? value : $"\"{value.Replace("\"", "\\\"")}\""; // 处理双引号转义 } }