-
Notifications
You must be signed in to change notification settings - Fork 123
Expand file tree
/
Copy pathPatternMatchingUtility.cs
More file actions
92 lines (76 loc) · 3.16 KB
/
PatternMatchingUtility.cs
File metadata and controls
92 lines (76 loc) · 3.16 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
namespace Microsoft.ComponentDetection.Common;
using System;
using System.Collections.Generic;
using System.IO.Enumeration;
using System.Linq;
public static class PatternMatchingUtility
{
public static bool MatchesPattern(string pattern, string fileName)
{
ArgumentNullException.ThrowIfNull(pattern);
ArgumentNullException.ThrowIfNull(fileName);
return IsPatternMatch(pattern, fileName.AsSpan());
}
/// <summary>
/// Returns the first matching pattern for <paramref name="fileName"/>.
/// Earlier patterns in <paramref name="patterns"/> have higher priority when multiple match.
/// </summary>
/// <returns>The first matching pattern, or <see langword="null"/> if no patterns match.</returns>
public static string? GetMatchingPattern(string fileName, IEnumerable<string> patterns)
{
ArgumentNullException.ThrowIfNull(fileName);
ArgumentNullException.ThrowIfNull(patterns);
return Compile(patterns).GetMatchingPattern(fileName.AsSpan());
}
public static CompiledMatcher Compile(IEnumerable<string> patterns)
{
ArgumentNullException.ThrowIfNull(patterns);
return patterns is string[] array ? Compile(array) : new(patterns.ToArray());
}
public static CompiledMatcher Compile(string[] patterns)
{
ArgumentNullException.ThrowIfNull(patterns);
return new(patterns);
}
private static string? GetFirstMatchingPattern(ReadOnlySpan<char> fileName, string[] patterns)
{
foreach (var pattern in patterns)
{
if (IsPatternMatch(pattern, fileName))
{
return pattern;
}
}
return null;
}
private static bool IsPatternMatch(string pattern, ReadOnlySpan<char> fileName) =>
FileSystemName.MatchesSimpleExpression(pattern, fileName, ignoreCase: true);
public sealed class CompiledMatcher
{
private readonly string[] patterns;
public CompiledMatcher(IEnumerable<string> patterns)
: this(patterns is string[] arr ? arr : (patterns ?? throw new ArgumentNullException(nameof(patterns))).ToArray())
{
}
internal CompiledMatcher(string[] patterns)
{
ArgumentNullException.ThrowIfNull(patterns);
this.patterns = (string[])patterns.Clone();
ValidatePatternElements(this.patterns);
}
public bool IsMatch(ReadOnlySpan<char> fileName) => GetFirstMatchingPattern(fileName, this.patterns) is not null;
/// <summary>
/// Returns the first matching pattern for <paramref name="fileName"/>.
/// Earlier patterns in the compiled set have higher priority when multiple match.
/// </summary>
/// <returns>The first matching pattern, or <see langword="null"/> if no patterns match.</returns>
public string? GetMatchingPattern(ReadOnlySpan<char> fileName) => GetFirstMatchingPattern(fileName, this.patterns);
private static void ValidatePatternElements(string[] patterns)
{
foreach (var pattern in patterns)
{
ArgumentNullException.ThrowIfNull(pattern);
}
}
}
}