namespace FileShare_Services.Core
{
///
/// Matches unified endpoint patterns and extracts simple route values.
///
internal static class ServiceEndpointPatternMatcher
{
///
/// Match literal segments and single-segment route parameters such as {id} or {id:int}.
///
public static bool TryMatch(
string pattern,
string path,
out Dictionary routeValues)
{
routeValues = new Dictionary(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;
}
///
/// 将路径按 / 拆分为非空片段数组。
///
/// 路径字符串。
/// 过滤空条目后的片段数组。
private static string[] SplitSegments(string value)
{
return value.Split('/', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
}
///
/// 尝试从 {name} 或 {name:constraint} 格式的片段中提取参数名称。
///
/// 模式片段。
/// 提取出的参数名称。
/// 该片段是路由参数时返回 true,否则 false。
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);
}
///
/// 检查路由值是否满足片段中的类型约束(目前仅支持 :int)。
///
/// 包含约束的模式片段。
/// 实际路径值。
/// 满足约束时返回 true。
private static bool MatchesConstraint(string segment, string value)
{
return !segment.EndsWith(":int}", StringComparison.OrdinalIgnoreCase)
|| int.TryParse(value, out _);
}
}
}