using System.Collections.Generic; using System.Linq; namespace SabreTools.Matching { /// /// Path matching criteria /// public class PathMatch : IMatch { /// /// String to match /// #if NETFRAMEWORK || NETCOREAPP public string? Needle { get; private set; } #else public string? Needle { get; init; } #endif /// /// Match exact casing instead of invariant /// public bool MatchExact { get; private set; } /// /// Match that values end with the needle and not just contains /// public bool UseEndsWith { get; private set; } /// /// Constructor /// /// String representing the search /// True to match exact casing, false otherwise /// True to match the end only, false for all contents public PathMatch(string? needle, bool matchExact = false, bool useEndsWith = false) { this.Needle = needle; this.MatchExact = matchExact; this.UseEndsWith = useEndsWith; } #region Matching /// /// Get if this match can be found in a stack /// /// List of strings to search for the given content /// Tuple of success and matched item public (bool, string?) Match(IEnumerable? stack) { // If either array is null or empty, we can't do anything if (stack == null || !stack.Any() || this.Needle == null || this.Needle.Length == 0) return (false, null); // Preprocess the needle, if necessary string procNeedle = this.MatchExact ? this.Needle : this.Needle.ToLowerInvariant(); foreach (string stackItem in stack) { // Preprocess the stack item, if necessary string procStackItem = this.MatchExact ? stackItem : stackItem.ToLowerInvariant(); if (this.UseEndsWith && procStackItem.EndsWith(procNeedle)) return (true, stackItem); else if (!this.UseEndsWith && procStackItem.Contains(procNeedle)) return (true, stackItem); } return (false, null); } #endregion } }