You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

132 lines
4.2 KiB

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;
}
}