diff --git a/IPA.Loader/Utilities/AlmostVersion.cs b/IPA.Loader/Utilities/AlmostVersion.cs index 46b12cdf..67563424 100644 --- a/IPA.Loader/Utilities/AlmostVersion.cs +++ b/IPA.Loader/Utilities/AlmostVersion.cs @@ -1,49 +1,74 @@ 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 { + /// + /// A type that wraps so that the string of the version is stored when the string is + /// not a valid . + /// public class AlmostVersion : IComparable, IComparable { - private Version semverForm = null; - private string strForm = null; - private StoredAs storedAs; - + /// + /// Represents a storage type of either parsed object or raw . + /// public enum StoredAs { + /// + /// The version was stored as a . + /// SemVer, + /// + /// The version was stored as a . + /// String } + /// + /// Creates a new with the version string provided in . + /// + /// the version string to store public AlmostVersion(string vertext) { if (!TryParseFrom(vertext, StoredAs.SemVer)) TryParseFrom(vertext, StoredAs.String); } + /// + /// Creates an from the provided in . + /// + /// the to store public AlmostVersion(Version ver) { - semverForm = ver; - storedAs = StoredAs.SemVer; + SemverValue = ver; + StorageMode = StoredAs.SemVer; } + /// + /// Creates an from the version string in stored using + /// the storage mode specified in . + /// + /// the text to parse as an + /// the storage mode to store the version in public AlmostVersion(string vertext, StoredAs mode) { if (!TryParseFrom(vertext, mode)) throw new ArgumentException($"{nameof(vertext)} could not be stored as {mode}!"); } + /// + /// Creates a new from the version string in stored the + /// same way as the passed in . + /// + /// the text to parse as an + /// an to copy the storage mode of public AlmostVersion(string vertext, AlmostVersion copyMode) { if (copyMode == null) throw new ArgumentNullException(nameof(copyMode)); - if (!TryParseFrom(vertext, copyMode.storedAs)) + if (!TryParseFrom(vertext, copyMode.StorageMode)) throw new ArgumentException($"{nameof(vertext)} could not be stored the same way as {copyMode}!"); } @@ -52,8 +77,8 @@ namespace IPA.Utilities if (mode == StoredAs.SemVer) try { - semverForm = new Version(str, true); - storedAs = StoredAs.SemVer; + SemverValue = new Version(str, true); + StorageMode = StoredAs.SemVer; return true; } catch @@ -62,71 +87,158 @@ namespace IPA.Utilities } else { - strForm = str; - storedAs = StoredAs.String; + StringValue = str; + StorageMode = StoredAs.String; return true; } } - public string StringValue => strForm; - - public Version SemverValue => semverForm; - + /// + /// The value of the if it was stored as a . + /// + /// the stored value as a , or if not stored as a string. + public string StringValue { get; private set; } = null; + + /// + /// The value of the if it was stored as a . + /// + /// the stored value as a , or if not stored as a version. + public Version SemverValue { get; private set; } = null; + + /// + /// The way the value is stored, whether it be as a or a . + /// + /// the storage mode used to store this value + public StoredAs StorageMode { get; private set; } + + // can I just this? + /// + /// Gets a string representation of the current version. If the value is stored as a string, this returns it. If it is + /// stored as a , it is equivalent to calling . + /// + /// a string representation of the current version + /// public override string ToString() => - storedAs == StoredAs.SemVer ? semverForm.ToString() : strForm; - + StorageMode == StoredAs.SemVer ? SemverValue.ToString() : StringValue; + + /// + /// Compares to the in using + /// or , depending on the current store. + /// + /// + /// The storage methods of the two objects must be the same, or this will throw an . + /// + /// the to compare to + /// less than 0 if is considered bigger than , 0 if equal, and greater than zero if smaller + /// public int CompareTo(AlmostVersion other) { if (other == null) return -1; - if (storedAs != other.storedAs) + if (StorageMode != other.StorageMode) throw new InvalidOperationException("Cannot compare AlmostVersions with different stores!"); - if (storedAs == StoredAs.SemVer) - return semverForm.CompareTo(other.semverForm); + if (StorageMode == StoredAs.SemVer) + return SemverValue.CompareTo(other.SemverValue); else - return strForm.CompareTo(other.strForm); + return StringValue.CompareTo(other.StringValue); } + /// + /// Compares to the in using . + /// + /// + /// The storage method of must be , else an will + /// be thrown. + /// + /// the to compare to + /// less than 0 if is considered bigger than , 0 if equal, and greater than zero if smaller + /// public int CompareTo(Version other) { - if (storedAs != StoredAs.SemVer) + if (StorageMode != StoredAs.SemVer) throw new InvalidOperationException("Cannot compare a SemVer version with an AlmostVersion stored as a string!"); - return semverForm.CompareTo(other); + return SemverValue.CompareTo(other); } + /// + /// Performs a strict equality check between and . + /// + /// + /// This may return where returns + /// + /// the object to compare to + /// if they are equal, otherwise + /// public override bool Equals(object obj) { return obj is AlmostVersion version && - semverForm == version.semverForm && - strForm == version.strForm && - storedAs == version.storedAs; + SemverValue == version.SemverValue && + StringValue == version.StringValue && + StorageMode == version.StorageMode; } + /// + /// Default generated hash code function generated by VS. + /// + /// a value unique to each object, except those that are considered equal by + /// public override int GetHashCode() { var hashCode = -126402897; - hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(semverForm); - hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(strForm); - hashCode = hashCode * -1521134295 + storedAs.GetHashCode(); + hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(SemverValue); + hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(StringValue); + hashCode = hashCode * -1521134295 + StorageMode.GetHashCode(); return hashCode; } + /// + /// Compares two versions, only taking into account the numeric part of the version if they are stored as , + /// or strict equality if they are stored as s. + /// + /// + /// This is a looser equality than , meaning that this may return where + /// does not. + /// + /// the first value to compare + /// the second value to compare + /// if they are mostly equal, otherwise + /// 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; + if (l == null && r == null) return true; + if (l == null || r == null) return false; + if (l.StorageMode != r.StorageMode) return false; + if (l.StorageMode == StoredAs.SemVer) + return Utils.VersionCompareNoPrerelease(l.SemverValue, r.SemverValue) == 0; else - return l.strForm == r.strForm; + return l.StringValue == r.StringValue; } + /// + /// The opposite of . Equivalent to !(l == r). + /// + /// the first value to compare + /// the second value to compare + /// if they are not mostly equal, otherwise + /// public static bool operator!=(AlmostVersion l, AlmostVersion r) => !(l == r); // implicitly convertible from Version + /// + /// Implicitly converts a to using . + /// + /// the to convert + /// public static implicit operator AlmostVersion(Version ver) => new AlmostVersion(ver); // implicitly convertible to Version - public static implicit operator Version(AlmostVersion av) => av.SemverValue; + /// + /// Implicitly converts an to , if applicable, using . + /// If not applicable, returns + /// + /// the to convert to a + /// + public static implicit operator Version(AlmostVersion av) => av?.SemverValue; } }