This repository has been archived on 2024-12-22. You can view files and clone it, but you cannot make any changes to it's state, such as pushing and creating new issues, pull requests or comments.
elliebot/src/EllieBot/_common/Replacements/Impl/ReplacementService.cs

137 lines
3.8 KiB
C#
Raw Normal View History

namespace EllieBot.Common;
public sealed class ReplacementService : IReplacementService, IEService
{
private readonly IReplacementPatternStore _repReg;
public ReplacementService(IReplacementPatternStore repReg)
{
_repReg = repReg;
}
public async ValueTask<SmartText> ReplaceAsync(SmartText input, ReplacementContext repCtx)
{
var reps = GetReplacementsForContext(repCtx);
var regReps = GetRegexReplacementsForContext(repCtx);
var inputData = GetInputData(repCtx);
var rep = new Replacer(reps.Values, regReps.Values, inputData);
return await rep.ReplaceAsync(input);
}
public async ValueTask<string?> ReplaceAsync(string input, ReplacementContext repCtx)
{
var reps = GetReplacementsForContext(repCtx);
var regReps = GetRegexReplacementsForContext(repCtx);
var inputData = GetInputData(repCtx);
var rep = new Replacer(reps.Values, regReps.Values, inputData);
return await rep.ReplaceAsync(input);
}
private object[] GetInputData(ReplacementContext repCtx)
{
var obj = new List<object>();
if (repCtx.Client is not null)
obj.Add(repCtx.Client);
if (repCtx.Guild is not null)
obj.Add(repCtx.Guild);
if (repCtx.User is not null)
obj.Add(repCtx.User);
if (repCtx.Channel is not null)
obj.Add(repCtx.Channel);
return obj.ToArray();
}
private IDictionary<string, ReplacementInfo> GetReplacementsForContext(ReplacementContext repCtx)
{
var reps = GetOriginalReplacementsForContext(repCtx);
foreach (var ovrd in repCtx.Overrides)
{
reps.Remove(ovrd.Token);
reps.TryAdd(ovrd.Token, ovrd);
}
return reps;
}
private IDictionary<string, RegexReplacementInfo> GetRegexReplacementsForContext(ReplacementContext repCtx)
{
var reps = GetOriginalRegexReplacementsForContext(repCtx);
foreach (var ovrd in repCtx.RegexOverrides)
{
reps.Remove(ovrd.Pattern);
reps.TryAdd(ovrd.Pattern, ovrd);
}
return reps;
}
private IDictionary<string, ReplacementInfo> GetOriginalReplacementsForContext(ReplacementContext repCtx)
{
var objs = new List<object>();
if (repCtx.Client is not null)
{
objs.Add(repCtx.Client);
}
if (repCtx.Channel is not null)
{
objs.Add(repCtx.Channel);
}
if (repCtx.User is not null)
{
objs.Add(repCtx.User);
}
if (repCtx.Guild is not null)
{
objs.Add(repCtx.Guild);
}
var types = objs.Map(x => x.GetType()).OrderBy(x => x.Name).ToHashSet();
return _repReg.Replacements
.Values
.Where(rep => rep.InputTypes.All(t => types.Any(x => x.IsAssignableTo((t)))))
.ToDictionary(rep => rep.Token, rep => rep);
}
private IDictionary<string, RegexReplacementInfo> GetOriginalRegexReplacementsForContext(ReplacementContext repCtx)
{
var objs = new List<object>();
if (repCtx.Client is not null)
{
objs.Add(repCtx.Client);
}
if (repCtx.Channel is not null)
{
objs.Add(repCtx.Channel);
}
if (repCtx.User is not null)
{
objs.Add(repCtx.User);
}
if (repCtx.Guild is not null)
{
objs.Add(repCtx.Guild);
}
var types = objs.Map(x => x.GetType()).OrderBy(x => x.Name).ToHashSet();
return _repReg.RegexReplacements
.Values
.Where(rep => rep.InputTypes.All(t => types.Any(x => x.IsAssignableTo((t)))))
.ToDictionary(rep => rep.Pattern, rep => rep);
}
}