using System.Security.Cryptography; using System.Text; using System.Text.RegularExpressions; namespace PluralKit.Core; public static class StringUtils { public static string GenerateToken() { // Results in a 64-byte Base64 string (no padding) var buf = RandomNumberGenerator.GetBytes(48); return Convert.ToBase64String(buf); } public static bool IsLongerThan(this string str, int length) { if (str != null) return str.Length > length; return false; } public static string ExtractCountryFlag(string flag) { if (flag.Length != 4) return null; try { var cp1 = char.ConvertToUtf32(flag, 0); var cp2 = char.ConvertToUtf32(flag, 2); if (cp1 < 0x1F1E6 || cp1 > 0x1F1FF) return null; if (cp2 < 0x1F1E6 || cp2 > 0x1F1FF) return null; return $"{(char)(cp1 - 0x1F1E6 + 'A')}{(char)(cp2 - 0x1F1E6 + 'A')}"; } catch (ArgumentException) { return null; } } public static string NullIfEmpty(this string input) { if (input == null) return null; if (input.Trim().Length == 0) return null; return input; } public static bool EmptyOrNull(this string input) { if (input == null) return true; if (input.Trim().Length == 0) return true; return false; } public static string NormalizeLineEndSpacing(this string input) => // iOS has a weird issue on embeds rendering newlines when there are spaces *just before* it // so we remove 'em - except in the case where there's a blockquote line that contains only // spaces (if we removed all the spaces there, the blockquote breaks horribly) Regex.Replace(input, "(?) *\n", "\n"); public static IReadOnlyList JoinPages(IEnumerable input, int characterLimit) => JoinPages(input, _ => characterLimit); public static IReadOnlyList JoinPages(IEnumerable input, Func characterLimitByPage) { var output = new List(); var buf = new StringBuilder(); foreach (var s in input) { var limit = characterLimitByPage.Invoke(output.Count); // Would adding this string put us over the limit? // (note: don't roll over if the buffer's already empty; this means an individual section is above the character limit. todo: truncate, then?) if (buf.Length > 0 && buf.Length + s.Length > limit) { // If so, "roll over" (before adding the string to the buffer) output.Add(buf.ToString()); buf.Clear(); } buf.Append(s); } // We most likely have something left over, so add that in too if (buf.Length > 0) output.Add(buf.ToString()); return output; } }