save progress
This commit is contained in:
91
src/__Libraries/StellaOps.Facet/FacetClassifier.cs
Normal file
91
src/__Libraries/StellaOps.Facet/FacetClassifier.cs
Normal file
@@ -0,0 +1,91 @@
|
||||
// <copyright file="FacetClassifier.cs" company="StellaOps">
|
||||
// Copyright (c) StellaOps. Licensed under AGPL-3.0-or-later.
|
||||
// </copyright>
|
||||
|
||||
namespace StellaOps.Facet;
|
||||
|
||||
/// <summary>
|
||||
/// Classifies files into facets based on selectors.
|
||||
/// </summary>
|
||||
public sealed class FacetClassifier
|
||||
{
|
||||
private readonly List<(IFacet Facet, GlobMatcher Matcher)> _facetMatchers;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="FacetClassifier"/> class.
|
||||
/// </summary>
|
||||
/// <param name="facets">Facets to classify against (will be sorted by priority).</param>
|
||||
public FacetClassifier(IEnumerable<IFacet> facets)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(facets);
|
||||
|
||||
// Sort by priority (lowest first = highest priority)
|
||||
_facetMatchers = facets
|
||||
.OrderBy(f => f.Priority)
|
||||
.Select(f => (f, GlobMatcher.ForFacet(f)))
|
||||
.ToList();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a classifier using built-in facets.
|
||||
/// </summary>
|
||||
public static FacetClassifier Default { get; } = new(BuiltInFacets.All);
|
||||
|
||||
/// <summary>
|
||||
/// Classify a file path to a facet.
|
||||
/// </summary>
|
||||
/// <param name="path">The file path to classify.</param>
|
||||
/// <returns>The matching facet or null if no match.</returns>
|
||||
public IFacet? Classify(string path)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(path);
|
||||
|
||||
// First matching facet wins (ordered by priority)
|
||||
foreach (var (facet, matcher) in _facetMatchers)
|
||||
{
|
||||
if (matcher.IsMatch(path))
|
||||
{
|
||||
return facet;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Classify a file and return the facet ID.
|
||||
/// </summary>
|
||||
/// <param name="path">The file path to classify.</param>
|
||||
/// <returns>The facet ID or null if no match.</returns>
|
||||
public string? ClassifyToId(string path)
|
||||
=> Classify(path)?.FacetId;
|
||||
|
||||
/// <summary>
|
||||
/// Classify multiple files efficiently.
|
||||
/// </summary>
|
||||
/// <param name="paths">The file paths to classify.</param>
|
||||
/// <returns>Dictionary from facet ID to matched paths.</returns>
|
||||
public Dictionary<string, List<string>> ClassifyMany(IEnumerable<string> paths)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(paths);
|
||||
|
||||
var result = new Dictionary<string, List<string>>();
|
||||
|
||||
foreach (var path in paths)
|
||||
{
|
||||
var facet = Classify(path);
|
||||
if (facet is not null)
|
||||
{
|
||||
if (!result.TryGetValue(facet.FacetId, out var list))
|
||||
{
|
||||
list = [];
|
||||
result[facet.FacetId] = list;
|
||||
}
|
||||
|
||||
list.Add(path);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user