Innovenergy_trunk/csharp/Lib/Utils/StringUtils.cs

385 lines
9.8 KiB
C#

using System.Globalization;
using System.Runtime.CompilerServices;
using static System.Math;
namespace InnovEnergy.Lib.Utils;
public static class StringUtils
{
public static String AppendPath(this String left, String right)
{
return left.TrimEnd('/') + '/' + right.TrimStart('/');
}
public static String RemoveSuffix(this String s, String suffix)
{
return s.Substring(0, s.LastIndexOf(suffix, StringComparison.Ordinal));
}
public static String SafeToString(this Object? o)
{
return o?.ToString() ?? "<null>";
}
public static Int32 NumberOfLines(this String s)
{
return s.Split(new[] {Environment.NewLine}, StringSplitOptions.None).Length;
}
public static String NewLineBefore(this String s)
{
return Environment.NewLine + s;
}
public static String AddTitle(this String s, String title)
{
return title.Underline() + s;
}
public static String Underline(this String s)
{
return s.NewLine() + "".PadRight(s.Length, '-').NewLine(2);
}
public static Boolean IsNullOrEmpty(this String? s)
{
return String.IsNullOrEmpty(s);
}
public static Boolean IsNullOrWhiteSpace(this String? s)
{
return String.IsNullOrWhiteSpace(s);
}
public static String Format(this Object value, String fmt)
{
return String.Format(fmt, value);
}
public static String NewLine(this String s)
{
return s + Environment.NewLine;
}
public static String NewLine(this String s, Int32 number)
{
return Enumerable
.Repeat(Environment.NewLine, number)
.Aggregate(s, (a, b) => a + b);
}
public static String Append(this String s, String other)
{
return s + other;
}
public static String SurroundWith(this String s, String beforeAfter)
{
return beforeAfter + s + beforeAfter;
}
public static String SurroundWith(this String s, String before, String after)
{
return before + s + after;
}
public static String ShellSingleQuote(this String s)
{
return $"'{s.Replace("'", @"'\''")}'";
}
// TODO: review
public static String Quote(this String s)
{
return s.Replace(@"\", @"\\")
.Replace("\"", "\\\"")
.SurroundWith("\"");
}
public static String Join(this String separator, params Object[] objects)
{
return String.Join(separator, objects);
}
public static String Join(this IEnumerable<String> strings)
{
return String.Join("", strings);
}
public static String JoinWith(this IEnumerable<String?> strings, String separator)
{
return String.Join(separator, strings);
}
public static String Indent(this String text)
{
return " ".SideBySideWith(text, "");
}
public static String Indent(this String text, Int32 amount)
{
return text.Indent("".PadLeft(amount));
}
public static String Indent(this String text, String indent)
{
return Enumerable
.Repeat(indent, text.SplitLines().Count)
.JoinLines()
.SideBySideWith(text, "");
}
public static IReadOnlyList<String> SplitLines(this String? s)
{
return s is null
? Array.Empty<String>()
: s.Split(new[] { Environment.NewLine }, StringSplitOptions.None);
}
public static String AlignLeft(this String s, Int32 width = 0)
{
var lines = s.SplitLines();
var w = Max(lines.Max(l => l.Length), width);
return lines
.Select(l => l.PadRight(w))
.JoinLines();
}
public static String AlignRight(this String s, Int32 width = 0)
{
var lines = s.SplitLines();
var w = Max(lines.Max(l => l.Length), width);
return lines
.Select(l => l.PadLeft(w))
.JoinLines();
}
public static String AlignCenterHorizontal(this String s, Int32 width = 0)
{
var lines = s.SplitLines();
var w = Max(lines.Max(l => l.Length), width);
return lines
.Select(l => l.PadLeft((w + l.Length) / 2).PadRight(w))
.JoinLines();
}
public static String AlignTop(this String s, Int32 height)
{
var lines = s.SplitLines();
var padding = Enumerable.Repeat("", Max(height - lines.Count, 0));
return lines
.Concat(padding)
.JoinLines();
}
public static String AlignBottom(this String s, Int32 height)
{
var lines = s.SplitLines();
var padding = Enumerable.Repeat("", Max(height - lines.Count, 0));
return padding
.Concat(lines)
.JoinLines();
}
public static String AlignCenterVertical(this String s, Int32 height)
{
var lines = s.SplitLines();
var nPadding = Max(height - lines.Count, 0);
var paddingTop = Enumerable.Repeat("", nPadding/2);
var paddingBottom = Enumerable.Repeat("", nPadding - nPadding / 2);
return paddingTop
.Concat(lines)
.Concat(paddingBottom)
.JoinLines();
}
public static String SideBySideWith(this String left, String right, String separator = " ")
{
var leftLines = left.SplitLines();
var rightLines = right.SplitLines();
var leftWidth = left.Width();
var nLines = Max(leftLines.Count, rightLines.Count);
var leftPadded = leftLines .PadEnd(nLines, "").Select(l => l.PadRight(leftWidth));
var rightPadded = rightLines.PadEnd(nLines, "");
return Enumerable
.Zip(leftPadded, rightPadded, (l, r) => String.Join(separator, l, r))
.JoinLines();
}
public static Int32 Width(this String str)
{
return str.SplitLines().Max(l => l.Length);
}
public static Int32 Height(this String str)
{
return str.SplitLines().Count;
}
public static String Join(this ITuple tuple)
{
return tuple.JoinWith("");
}
public static String JoinWith(this ITuple tuple, String separator)
{
return tuple
.ToEnumerable()
.Select(t => t.SafeToString())
.JoinWith(separator);
}
public static String JoinWith<T>(this IEnumerable<T> args, String separator)
{
return String.Join(separator, args);
}
public static IEnumerable<String> GetLinesStartingWith(this IEnumerable<String> lines, String prefix)
{
return lines.Where(l => l.StartsWith(prefix));
}
public static String GetLineStartingWith(this IEnumerable<String> lines, String prefix)
{
return lines
.GetLinesStartingWith(prefix)
.Single();
}
public static Boolean EndsWith(this String str, Char c)
{
if (str.Length <= 0)
return false;
return str[^1] == c;
}
public static String AfterFirst(this String str, Char separator)
{
return str.Substring(str.IndexOf(separator) + 1);
}
public static String AfterLast(this String str, Char separator)
{
return str.Substring(str.LastIndexOf(separator) + 1);
}
public static String UntilLast(this String str, Char separator)
{
var i = str.LastIndexOf(separator);
return i >= 0
? str[..i]
: str;
}
public static String UntilFirst(this String str, Char separator)
{
var i = str.IndexOf(separator);
return i >= 0
? str[..i]
: str;
}
public static Boolean Contains(this String? str, String value, CompareOptions compareOptions)
{
return Contains(str, value, compareOptions, CultureInfo.InvariantCulture);
}
public static Boolean Contains(this String? str, String value, CompareOptions compareOptions, CultureInfo culture)
{
return str is not null && culture.CompareInfo.IndexOf(str, value, compareOptions) != -1;
}
public static String NewLine(this Object s)
{
return s + Environment.NewLine;
}
public static String Spaces(this String s, Int32 count = 4)
{
return s.PadRight(s.Length + count);
}
public static String JoinNonEmptyLines(this IEnumerable<String> lines)
{
return String.Join(Environment.NewLine, lines.Unless(String.IsNullOrWhiteSpace));
}
public static String JoinLines(this IEnumerable<String> lines)
{
return String.Join(Environment.NewLine, lines);
}
public static String JoinLines(params String[] lines)
{
return String.Join(Environment.NewLine, lines);
}
public static String SeparatedBy(this IEnumerable<String> s, String separator)
{
return String.Join(separator, s);
}
public static Boolean IsInteger(this String s)
{
return Int64.TryParse(s, out var n);
}
public static String TrimStart(this String target, String trimString)
{
if (String.IsNullOrEmpty(trimString)) return target;
var result = target;
while (result.StartsWith(trimString))
result = result[trimString.Length..];
return result;
}
public static String TrimEnd(this String target, String trimString)
{
if (String.IsNullOrEmpty(trimString))
return target;
var result = target;
while (result.EndsWith(trimString))
result = result[..^trimString.Length];
return result;
}
public static String EnsureStartsWith(this String target, String prefix)
{
return $"{prefix}{target.TrimStart(prefix)}";
}
public static String EnsureEndsWith(this String target, String postfix)
{
return $"{target.TrimEnd(postfix)}{postfix}";
}
}