using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Text; using System.Text.Encodings.Web; using EntityFrameworkCore.Projectables; namespace Iceshrimp.Backend.Core.Extensions; public static class StringExtensions { private static readonly IdnMapping IdnMapping = new(); public static bool EqualsInvariant(this string? s1, string? s2) => string.Equals(s1, s2, StringComparison.InvariantCulture); public static bool EqualsIgnoreCase(this string? s1, string s2) => string.Equals(s1, s2, StringComparison.InvariantCultureIgnoreCase); public static string Truncate(this string target, int maxLength) { return target[..Math.Min(target.Length, maxLength)]; } public static string TruncateEllipsis(this string target, int maxLength) { if (target.Length <= maxLength) return target; return target[..(maxLength-3)] + "..."; } private static string ToPunycode(this string target) { return target.Length > 0 ? IdnMapping.GetAscii(target) : target; } public static string ToPunycodeLower(this string target) { return ToPunycode(target).ToLowerInvariant(); } public static string FromPunycode(this string target) { return IdnMapping.GetUnicode(target); } public static string ToTitleCase(this string input) => input switch { null => throw new ArgumentNullException(nameof(input)), "" => throw new ArgumentException(@$"{nameof(input)} cannot be empty", nameof(input)), _ => string.Concat(input[0].ToString().ToUpper(), input.AsSpan(1)) }; public static string UrlEncode(this string input) => UrlEncoder.Default.Encode(input); } [SuppressMessage("ReSharper", "StringCompareToIsCultureSpecific")] public static class ProjectableStringExtensions { [Projectable] public static bool IsLessThan(this string a, string b) => a.CompareTo(b) < 0; [Projectable] public static bool IsLessOrEqualTo(this string a, string b) => a.CompareTo(b) <= 0; [Projectable] public static bool IsGreaterThan(this string a, string b) => a.CompareTo(b) > 0; [Projectable] public static bool IsGreaterOrEqualTo(this string a, string b) => a.CompareTo(b) >= 0; } public static class StringBuilderExtensions { private const char NewLineLf = '\n'; /// /// Equivalent to .AppendLine, but always uses \n instead of Environment.NewLine /// public static StringBuilder AppendLineLf(this StringBuilder sb, string? value) { sb.Append(value); return sb.Append(NewLineLf); } }