-
-
Save haacked/adbdc12fc6c8ea21d639deb3763fdd98 to your computer and use it in GitHub Desktop.
Code from Abbot's Argument Parsing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Text.RegularExpressions; | |
using Serious.Abbot.Messages; | |
using Serious.Abbot.Scripting; | |
namespace Serious.Abbot.Models | |
{ | |
public class Arguments : List<IArgument>, IArguments | |
{ | |
static readonly MissingArgument MissingArgument = new(); | |
static readonly Regex Tokenized = new(@"'(?<value>.+?)'|[\""](?<value>.+?)[\""]|(?<value>[^ ]+)", RegexOptions.Compiled); | |
public Arguments(string arguments) | |
: this(ParseTokens(Normalize(arguments))) | |
{ | |
} | |
Arguments((string, IEnumerable<Argument>) normalizedAndTokenized) | |
{ | |
var (value, args) = normalizedAndTokenized; | |
Value = value; | |
AddRange(args); | |
} | |
public Arguments(IEnumerable<IArgument> arguments, string rawArguments) | |
{ | |
Value = rawArguments; | |
AddRange(arguments); | |
} | |
Arguments(IList<IArgument> arguments) | |
: this(arguments, string.Join(' ', arguments.Cast<IOriginalArgument>().Select(og => og.OriginalText))) | |
{ | |
} | |
public void Deconstruct(out IArgument first, out IArgument second) | |
{ | |
first = ElementAt(0); | |
second = Rest(1); | |
} | |
public void Deconstruct(out IArgument first, out IArgument second, out IArgument third) | |
{ | |
first = ElementAt(0); | |
second = ElementAt(1); | |
third = Rest(2); | |
} | |
public void Deconstruct(out IArgument first, out IArgument second, out IArgument third, out IArgument fourth) | |
{ | |
first = ElementAt(0); | |
second = ElementAt(1); | |
third = ElementAt(2); | |
fourth = Rest(3); | |
} | |
IArgument ElementAt(int index) | |
{ | |
return Count > index ? this[index] : MissingArgument; | |
} | |
public string Value { get; } | |
IArgument Rest(int index) | |
{ | |
return index >= Count | |
? MissingArgument | |
: index == Count - 1 | |
? this[index] | |
: new Arguments(this.Skip(index).ToList()); | |
} | |
public override string ToString() | |
{ | |
return Value; | |
} | |
static (string, IEnumerable<Argument>) ParseTokens(string arguments) | |
{ | |
return (arguments, Tokenized.Matches(arguments) | |
.Select(m => new Argument { Value = m.Groups["value"].Value, OriginalText = m.Value })); | |
} | |
static readonly Regex FixUrlRegex = new(@"(?<=\s|^|"")<(?<url>https?://.*?)(?:\|.*?)?>(?=""|\s|$)", RegexOptions.Compiled); | |
static string Normalize(string value) | |
{ | |
var normalized = value.Trim() | |
.Replace("“", "\"", StringComparison.Ordinal) | |
.Replace("”", "\"", StringComparison.Ordinal) | |
.Replace("‘", "'", StringComparison.Ordinal) | |
.Replace("’", "'", StringComparison.Ordinal); | |
return FixUrlRegex.Replace(normalized, "${url}"); | |
} | |
} | |
} | |
using Serious.Abbot.Scripting; | |
namespace Serious.Abbot.Messages | |
{ | |
public class Argument : IOriginalArgument | |
{ | |
public Argument() | |
{ | |
} | |
public Argument(IOriginalArgument argument) : this(argument.Value, argument.OriginalText) | |
{ | |
} | |
public Argument(string value) | |
{ | |
Value = value; | |
OriginalText = value; | |
} | |
public Argument(string value, string originalText) | |
{ | |
Value = value; | |
OriginalText = originalText; | |
} | |
public string Value { get; set; } = string.Empty; | |
public string OriginalText { get; set; } = string.Empty; | |
public override string ToString() | |
{ | |
return Value; | |
} | |
} | |
public class MentionArgument : Argument, IMentionArgument | |
{ | |
public MentionArgument() | |
{ | |
} | |
public MentionArgument(IOriginalArgument argument, IChatUser mentioned) : base(argument) | |
{ | |
Mentioned = mentioned; | |
} | |
public IChatUser Mentioned { get; set; } = null!; | |
} | |
public class MissingArgument : Argument, IMissingArgument | |
{ | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment