public static void FormatArgCount(ArgCountRange range, out CountableString result) { // (1,_) uncapped => "1 or more arguments" if (range.MaxArgs == null) { result = new CountableString(string.Format(CultureInfo.InvariantCulture, "{0} or more", range.MinArgs), true); return; } // (1,1) => "exactly 1 argument" if (range.MaxArgs == range.MinArgs) { result = new CountableString(string.Format(CultureInfo.InvariantCulture, "exactly {0}", range.MinArgs), range.MinArgs != 1); return; } // (0,1) => "at most 1 argument" if (range.MinArgs == 0) { result = new CountableString(string.Format(CultureInfo.InvariantCulture, "at most {0}", range.MaxArgs), range.MaxArgs != 1); return; } // (1,2) => "1 or 2 arguments" if (range.MaxArgs == range.MinArgs + 1) { result = new CountableString(string.Format(CultureInfo.InvariantCulture, "{0} or {1}", range.MinArgs, range.MaxArgs), true); return; } // (1,3) => "1 to 3 arguments" result = new CountableString(string.Format(CultureInfo.InvariantCulture, "{0} to {1}", range.MinArgs, range.MaxArgs), true); }
/// <exception cref="ArgumentException">No ranges provided</exception> public static void FormatArgCount([NotNull] IEnumerable <ArgCountRange> ranges, out CountableString result) { var allCounts = new List <int>(); bool uncapped = false; foreach (var r in ranges) { if (r.MaxArgs == null) { uncapped = true; allCounts.Add(r.MinArgs); } else { for (int i = r.MinArgs; i <= r.MaxArgs; i++) { allCounts.Add(i); } } } if (allCounts.Count == 0) { throw new ArgumentException("No ranges provided", nameof(ranges)); } allCounts.Sort(); // (1,2), (2,4) => (1,4) var collapsed = Collapse( allCounts.Select(c => new { min = c, max = c }), (a, b) => b.min <= a.max + 1, (a, b) => new { a.min, b.max }) .ToArray(); if (collapsed.Length == 1) { var r = collapsed[0]; var range = new ArgCountRange(r.min, uncapped ? (int?)null : r.max); FormatArgCount(range, out result); return; } // disjoint ranges var unrolled = from r in collapsed from n in Enumerable.Range(r.min, r.max - r.min + 1) select n.ToString(CultureInfo.InvariantCulture); if (uncapped) { unrolled = unrolled.Concat(Enumerable.Repeat("more", 1)); } result = new CountableString(EnglishJoin(unrolled, "or"), true); }