FileShare/FileShare-Services/Core/ServiceEndpointPatternMatcher.cs
luoqian d93098638d docs: 补全 C# XML 文档注释,覆盖所有公开与内部成员
为 14 个项目中缺少 XML 注释的类、接口、方法、属性、字段、record、
枚举等成员补全中文文档注释。接口方法在接口层定义完整注释,实现类
使用 <inheritdoc /> 引用。私有辅助方法结合业务语义编写注释。

扫描结果:missing-csharp-docs.txt 缺失项归零。
构建结果:0 警告,0 错误。

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-22 14:45:07 +08:00

93 lines
3.5 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

namespace FileShare_Services.Core
{
/// <summary>
/// Matches unified endpoint patterns and extracts simple route values.
/// </summary>
internal static class ServiceEndpointPatternMatcher
{
/// <summary>
/// Match literal segments and single-segment route parameters such as {id} or {id:int}.
/// </summary>
public static bool TryMatch(
string pattern,
string path,
out Dictionary<string, string> routeValues)
{
routeValues = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
var patternSegments = SplitSegments(pattern);
var pathSegments = SplitSegments(path);
if (patternSegments.Length != pathSegments.Length)
{
return false;
}
for (var index = 0; index < patternSegments.Length; index++)
{
var patternSegment = patternSegments[index];
var pathSegment = pathSegments[index];
if (TryGetParameterName(patternSegment, out var parameterName))
{
if (!MatchesConstraint(patternSegment, pathSegment))
{
return false;
}
routeValues[parameterName] = Uri.UnescapeDataString(pathSegment);
continue;
}
if (!string.Equals(patternSegment, pathSegment, StringComparison.OrdinalIgnoreCase))
{
return false;
}
}
return true;
}
/// <summary>
/// 将路径按 <c>/</c> 拆分为非空片段数组。
/// </summary>
/// <param name="value">路径字符串。</param>
/// <returns>过滤空条目后的片段数组。</returns>
private static string[] SplitSegments(string value)
{
return value.Split('/', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
}
/// <summary>
/// 尝试从 <c>{name}</c> 或 <c>{name:constraint}</c> 格式的片段中提取参数名称。
/// </summary>
/// <param name="segment">模式片段。</param>
/// <param name="parameterName">提取出的参数名称。</param>
/// <returns>该片段是路由参数时返回 true否则 false。</returns>
private static bool TryGetParameterName(string segment, out string parameterName)
{
parameterName = string.Empty;
if (segment.Length < 3 || segment[0] != '{' || segment[^1] != '}')
{
return false;
}
var token = segment[1..^1];
var constraintIndex = token.IndexOf(':');
parameterName = constraintIndex >= 0 ? token[..constraintIndex] : token;
return !string.IsNullOrWhiteSpace(parameterName);
}
/// <summary>
/// 检查路由值是否满足片段中的类型约束(目前仅支持 <c>:int</c>)。
/// </summary>
/// <param name="segment">包含约束的模式片段。</param>
/// <param name="value">实际路径值。</param>
/// <returns>满足约束时返回 true。</returns>
private static bool MatchesConstraint(string segment, string value)
{
return !segment.EndsWith(":int}", StringComparison.OrdinalIgnoreCase)
|| int.TryParse(value, out _);
}
}
}