namespace StellaOps.Feedser.Merge.Comparers;
using System.Diagnostics.CodeAnalysis;
using Semver;
///
/// Provides helpers to interpret introduced/fixed/lastAffected SemVer ranges and compare versions.
///
public static class SemanticVersionRangeResolver
{
public static bool TryParse(string? value, [NotNullWhen(true)] out SemVersion? result)
=> SemVersion.TryParse(value, SemVersionStyles.Any, out result);
public static SemVersion Parse(string value)
=> SemVersion.Parse(value, SemVersionStyles.Any);
///
/// Resolves the effective start and end versions using introduced/fixed/lastAffected semantics.
///
public static (SemVersion? introduced, SemVersion? exclusiveUpperBound, SemVersion? inclusiveUpperBound) ResolveWindows(
string? introduced,
string? fixedVersion,
string? lastAffected)
{
var introducedVersion = TryParse(introduced, out var parsedIntroduced) ? parsedIntroduced : null;
var fixedVersionParsed = TryParse(fixedVersion, out var parsedFixed) ? parsedFixed : null;
var lastAffectedVersion = TryParse(lastAffected, out var parsedLast) ? parsedLast : null;
SemVersion? exclusiveUpper = null;
SemVersion? inclusiveUpper = null;
if (fixedVersionParsed is not null)
{
exclusiveUpper = fixedVersionParsed;
}
else if (lastAffectedVersion is not null)
{
inclusiveUpper = lastAffectedVersion;
exclusiveUpper = NextPatch(lastAffectedVersion);
}
return (introducedVersion, exclusiveUpper, inclusiveUpper);
}
public static int Compare(string? left, string? right)
{
var leftParsed = TryParse(left, out var leftSemver);
var rightParsed = TryParse(right, out var rightSemver);
if (leftParsed && rightParsed)
{
return SemVersion.CompareSortOrder(leftSemver, rightSemver);
}
if (leftParsed)
{
return 1;
}
if (rightParsed)
{
return -1;
}
return string.Compare(left, right, StringComparison.Ordinal);
}
private static SemVersion NextPatch(SemVersion version)
{
return new SemVersion(version.Major, version.Minor, version.Patch + 1);
}
}