using System.Collections.Generic; using System.IO; namespace SabreTools.Matching { /// /// Path matching criteria /// public class PathMatch : IMatch { /// /// String to match /// public string Needle { get; } /// /// Match casing instead of invariant /// private readonly bool _matchCase; /// /// Match that values end with the needle and not just contains /// private readonly bool _useEndsWith; /// /// Constructor /// /// String representing the search /// True to match exact casing, false otherwise /// True to match the end only, false for contains /// /// Thrown if has a length of 0. /// public PathMatch(string needle, bool matchCase = false, bool useEndsWith = false) { // Validate the inputs if (needle.Length == 0) throw new InvalidDataException(nameof(needle)); Needle = needle; _matchCase = matchCase; _useEndsWith = useEndsWith; } #region Conversion /// /// Allow conversion from string to PathMatch /// public static implicit operator PathMatch(string needle) => new(needle); #endregion #region Matching /// /// Get if this match can be found in a stack /// /// Array of strings to search for the given content /// Matched item on success, null on error public string? Match(string[]? stack) => Match(stack is null ? null : new List(stack)); /// /// Get if this match can be found in a stack /// /// List of strings to search for the given content /// Matched item on success, null on error public string? Match(List? stack) { // If either set is null or empty if (stack is null || stack.Count == 0 || Needle.Length == 0) return null; // Preprocess the needle, if necessary string procNeedle = _matchCase ? Needle : Needle.ToLowerInvariant(); foreach (string stackItem in stack) { // Preprocess the stack item, if necessary string procStackItem = _matchCase ? stackItem : stackItem.ToLowerInvariant(); if (_useEndsWith && procStackItem.EndsWith(procNeedle)) return stackItem; else if (!_useEndsWith && procStackItem.Contains(procNeedle)) return stackItem; } return null; } #endregion } }