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
}
}