|
@ -0,0 +1,132 @@ |
|
|
|
|
|
using System; |
|
|
|
|
|
using System.Collections.Generic; |
|
|
|
|
|
using System.Linq; |
|
|
|
|
|
using System.Text; |
|
|
|
|
|
using System.Threading.Tasks; |
|
|
|
|
|
using SemVer; |
|
|
|
|
|
using Version = SemVer.Version; |
|
|
|
|
|
|
|
|
|
|
|
namespace IPA.Utilities |
|
|
|
|
|
{ |
|
|
|
|
|
public class AlmostVersion : IComparable<AlmostVersion>, IComparable<Version> |
|
|
|
|
|
{ |
|
|
|
|
|
private Version semverForm = null; |
|
|
|
|
|
private string strForm = null; |
|
|
|
|
|
private StoredAs storedAs; |
|
|
|
|
|
|
|
|
|
|
|
public enum StoredAs |
|
|
|
|
|
{ |
|
|
|
|
|
SemVer, |
|
|
|
|
|
String |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public AlmostVersion(string vertext) |
|
|
|
|
|
{ |
|
|
|
|
|
if (!TryParseFrom(vertext, StoredAs.SemVer)) |
|
|
|
|
|
TryParseFrom(vertext, StoredAs.String); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public AlmostVersion(Version ver) |
|
|
|
|
|
{ |
|
|
|
|
|
semverForm = ver; |
|
|
|
|
|
storedAs = StoredAs.SemVer; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public AlmostVersion(string vertext, StoredAs mode) |
|
|
|
|
|
{ |
|
|
|
|
|
if (!TryParseFrom(vertext, mode)) |
|
|
|
|
|
throw new ArgumentException($"{nameof(vertext)} could not be stored as {mode}!"); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public AlmostVersion(string vertext, AlmostVersion copyMode) |
|
|
|
|
|
{ |
|
|
|
|
|
if (copyMode == null) |
|
|
|
|
|
throw new ArgumentNullException(nameof(copyMode)); |
|
|
|
|
|
|
|
|
|
|
|
if (!TryParseFrom(vertext, copyMode.storedAs)) |
|
|
|
|
|
throw new ArgumentException($"{nameof(vertext)} could not be stored the same way as {copyMode}!"); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private bool TryParseFrom(string str, StoredAs mode) |
|
|
|
|
|
{ |
|
|
|
|
|
if (mode == StoredAs.SemVer) |
|
|
|
|
|
try |
|
|
|
|
|
{ |
|
|
|
|
|
semverForm = new Version(str, true); |
|
|
|
|
|
storedAs = StoredAs.SemVer; |
|
|
|
|
|
return true; |
|
|
|
|
|
} |
|
|
|
|
|
catch |
|
|
|
|
|
{ |
|
|
|
|
|
return false; |
|
|
|
|
|
} |
|
|
|
|
|
else |
|
|
|
|
|
{ |
|
|
|
|
|
strForm = str; |
|
|
|
|
|
storedAs = StoredAs.String; |
|
|
|
|
|
return true; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public string StringValue => strForm; |
|
|
|
|
|
|
|
|
|
|
|
public Version SemverValue => semverForm; |
|
|
|
|
|
|
|
|
|
|
|
public override string ToString() => |
|
|
|
|
|
storedAs == StoredAs.SemVer ? semverForm.ToString() : strForm; |
|
|
|
|
|
|
|
|
|
|
|
public int CompareTo(AlmostVersion other) |
|
|
|
|
|
{ |
|
|
|
|
|
if (other == null) return -1; |
|
|
|
|
|
if (storedAs != other.storedAs) |
|
|
|
|
|
throw new InvalidOperationException("Cannot compare AlmostVersions with different stores!"); |
|
|
|
|
|
|
|
|
|
|
|
if (storedAs == StoredAs.SemVer) |
|
|
|
|
|
return semverForm.CompareTo(other.semverForm); |
|
|
|
|
|
else |
|
|
|
|
|
return strForm.CompareTo(other.strForm); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public int CompareTo(Version other) |
|
|
|
|
|
{ |
|
|
|
|
|
if (storedAs != StoredAs.SemVer) |
|
|
|
|
|
throw new InvalidOperationException("Cannot compare a SemVer version with an AlmostVersion stored as a string!"); |
|
|
|
|
|
|
|
|
|
|
|
return semverForm.CompareTo(other); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public override bool Equals(object obj) |
|
|
|
|
|
{ |
|
|
|
|
|
return obj is AlmostVersion version && |
|
|
|
|
|
semverForm == version.semverForm && |
|
|
|
|
|
strForm == version.strForm && |
|
|
|
|
|
storedAs == version.storedAs; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public override int GetHashCode() |
|
|
|
|
|
{ |
|
|
|
|
|
var hashCode = -126402897; |
|
|
|
|
|
hashCode = hashCode * -1521134295 + EqualityComparer<Version>.Default.GetHashCode(semverForm); |
|
|
|
|
|
hashCode = hashCode * -1521134295 + EqualityComparer<string>.Default.GetHashCode(strForm); |
|
|
|
|
|
hashCode = hashCode * -1521134295 + storedAs.GetHashCode(); |
|
|
|
|
|
return hashCode; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public static bool operator==(AlmostVersion l, AlmostVersion r) |
|
|
|
|
|
{ |
|
|
|
|
|
if (l.storedAs != r.storedAs) return false; |
|
|
|
|
|
if (l.storedAs == StoredAs.SemVer) |
|
|
|
|
|
return Utils.VersionCompareNoPrerelease(l.semverForm, r.semverForm) == 0; |
|
|
|
|
|
else |
|
|
|
|
|
return l.strForm == r.strForm; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public static bool operator!=(AlmostVersion l, AlmostVersion r) => !(l == r); |
|
|
|
|
|
|
|
|
|
|
|
// implicitly convertible from Version
|
|
|
|
|
|
public static implicit operator AlmostVersion(Version ver) => new AlmostVersion(ver); |
|
|
|
|
|
|
|
|
|
|
|
// implicitly convertible to Version
|
|
|
|
|
|
public static implicit operator Version(AlmostVersion av) => av.SemverValue; |
|
|
|
|
|
} |
|
|
|
|
|
} |