using System.Text; using System.Text.RegularExpressions; namespace EllieBot.Common; public sealed partial class Replacer { private readonly IEnumerable _reps; private readonly IEnumerable _regexReps; private readonly object[] _inputData; // [GeneratedRegex(@"\%[\p{L}\p{N}\._]*[\p{L}\p{N}]+[\p{L}\p{N}\._]*\%")] // private static partial Regex TokenExtractionRegex(); public Replacer(IEnumerable reps, IEnumerable regexReps, object[] inputData) { _reps = reps; _inputData = inputData; _regexReps = regexReps; } public async ValueTask ReplaceAsync(string? input) { if (string.IsNullOrWhiteSpace(input)) return input; // var matches = TokenExtractionRegex().IsMatch(input); // if (matches) // { foreach (var rep in _reps) { if (input.Contains(rep.Token, StringComparison.InvariantCulture)) { var objs = GetParams(rep.InputTypes); input = input.Replace(rep.Token, await rep.GetValueAsync(objs), StringComparison.InvariantCulture); } } // } foreach (var rep in _regexReps) { var sb = new StringBuilder(); var objs = GetParams(rep.InputTypes); var match = rep.Regex.Match(input); if (match.Success) { sb.Append(input, 0, match.Index) .Append(await rep.GetValueAsync(match, objs)); var lastIndex = match.Index + match.Length; sb.Append(input, lastIndex, input.Length - lastIndex); input = sb.ToString(); } } return input; } private object?[]? GetParams(IReadOnlyCollection inputTypes) { if (inputTypes.Count == 0) return null; var objs = new List(); foreach (var t in inputTypes) { var datum = _inputData.FirstOrDefault(x => x.GetType().IsAssignableTo(t)); if (datum is not null) objs.Add(datum); } return objs.ToArray(); } public async ValueTask ReplaceAsync(SmartText data) => data switch { SmartEmbedText embedData => await ReplaceAsync(embedData) with { PlainText = await ReplaceAsync(embedData.PlainText), Color = embedData.Color }, SmartPlainText plain => await ReplaceAsync(plain), SmartEmbedTextArray arr => await ReplaceAsync(arr), _ => throw new ArgumentOutOfRangeException(nameof(data), "Unsupported argument type") }; private async Task ReplaceAsync(SmartEmbedTextArray embedArr) => new() { Embeds = await embedArr.Embeds.Map(async e => await ReplaceAsync(e) with { Color = e.Color }) .WhenAll(), Content = await ReplaceAsync(embedArr.Content) }; private async ValueTask ReplaceAsync(SmartPlainText plain) => await ReplaceAsync(plain.Text); private async Task ReplaceAsync(T embedData) where T : SmartEmbedTextBase, new() { var newEmbedData = new T { Description = await ReplaceAsync(embedData.Description), Title = await ReplaceAsync(embedData.Title), Thumbnail = await ReplaceAsync(embedData.Thumbnail), Image = await ReplaceAsync(embedData.Image), Url = await ReplaceAsync(embedData.Url), Author = embedData.Author is null ? null : new() { Name = await ReplaceAsync(embedData.Author.Name), IconUrl = await ReplaceAsync(embedData.Author.IconUrl) }, Fields = await Task.WhenAll(embedData .Fields? .Map(async f => new SmartTextEmbedField { Name = await ReplaceAsync(f.Name), Value = await ReplaceAsync(f.Value), Inline = f.Inline }) ?? []), Footer = embedData.Footer is null ? null : new() { Text = await ReplaceAsync(embedData.Footer.Text), IconUrl = await ReplaceAsync(embedData.Footer.IconUrl) } }; return newEmbedData; } }