using System; using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Text.RegularExpressions; using UnityEngine; namespace NugetForUnity.Models { /// /// Represents a unity version. /// internal readonly struct UnityVersion : IComparable { private readonly int build; private readonly int major; private readonly int minor; private readonly char release; private readonly int revision; /// /// Initializes a new instance of the struct. /// /// Major version number. /// Minor version number. /// Revision number. /// Release flag. If 'f', official release. If 'p' patch release. /// Build number. public UnityVersion(int major, int minor, int revision, char release, int build) { this.major = major; this.minor = minor; this.revision = revision; this.release = release; this.build = build; } /// /// Initializes a new instance of the struct. /// /// A string representation of Unity version. /// Cannot parse version. [SuppressMessage("ReSharper", "MemberCanBePrivate.Local", Justification = "Called by Unit Test.")] public UnityVersion(string version) { var match = Regex.Match(version, @"(\d+)\.(\d+)\.(\d+)([fpba])(\d+)"); if (!match.Success) { throw new ArgumentException("Invalid unity version"); } major = int.Parse(match.Groups[1].Value, CultureInfo.InvariantCulture); minor = int.Parse(match.Groups[2].Value, CultureInfo.InvariantCulture); revision = int.Parse(match.Groups[3].Value, CultureInfo.InvariantCulture); release = match.Groups[4].Value[0]; build = int.Parse(match.Groups[5].Value, CultureInfo.InvariantCulture); } /// /// Gets current version from Application.unityVersion. /// [SuppressMessage("ReSharper", "AutoPropertyCanBeMadeGetOnly.Local", Justification = "Property setter needed for unit test")] public static UnityVersion Current { get; private set; } = new UnityVersion(Application.unityVersion); /// /// Checks to see if the left is less than the right. /// /// The first value to compare. /// The second value to compare. /// True if left is less than the right. public static bool operator <(in UnityVersion left, in UnityVersion right) { return left.CompareTo(right) < 0; } /// /// Checks to see if the left is less than or equal to the right. /// /// The first value to compare. /// The second value to compare. /// True if left is less than or equal to the right. public static bool operator <=(in UnityVersion left, in UnityVersion right) { return left.CompareTo(right) <= 0; } /// /// Checks to see if the left is greater than the right. /// /// The first value to compare. /// The second value to compare. /// True if left is greater than the right. public static bool operator >(in UnityVersion left, in UnityVersion right) { return left.CompareTo(right) > 0; } /// /// Checks to see if the left is greater than or equal to the right. /// /// The first value to compare. /// The second value to compare. /// True if left is greater than or equal to the right. public static bool operator >=(in UnityVersion left, in UnityVersion right) { return left.CompareTo(right) >= 0; } /// public int CompareTo(UnityVersion other) { return Compare(this, other); } private static int Compare(in UnityVersion a, in UnityVersion b) { if (a.major < b.major) { return -1; } if (a.major > b.major) { return 1; } if (a.minor < b.minor) { return -1; } if (a.minor > b.minor) { return 1; } if (a.revision < b.revision) { return -1; } if (a.revision > b.revision) { return 1; } if (a.release < b.release) { return -1; } if (a.release > b.release) { return 1; } if (a.build < b.build) { return -1; } if (a.build > b.build) { return 1; } return 0; } } }