forked from EllieBotDevs/elliebot
141 lines
No EOL
4.8 KiB
C#
141 lines
No EOL
4.8 KiB
C#
using System.Text;
|
|
using System.Text.RegularExpressions;
|
|
|
|
namespace EllieBot.Common;
|
|
|
|
public sealed partial class Replacer
|
|
{
|
|
private readonly IEnumerable<ReplacementInfo> _reps;
|
|
private readonly IEnumerable<RegexReplacementInfo> _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<ReplacementInfo> reps, IEnumerable<RegexReplacementInfo> regexReps, object[] inputData)
|
|
{
|
|
_reps = reps;
|
|
_inputData = inputData;
|
|
_regexReps = regexReps;
|
|
}
|
|
|
|
public async ValueTask<string?> 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<Type> inputTypes)
|
|
{
|
|
if (inputTypes.Count == 0)
|
|
return null;
|
|
|
|
var objs = new List<object>();
|
|
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<SmartText> 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<SmartEmbedTextArray> 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<SmartPlainText> ReplaceAsync(SmartPlainText plain)
|
|
=> await ReplaceAsync(plain.Text);
|
|
|
|
private async Task<T> ReplaceAsync<T>(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;
|
|
}
|
|
} |