namespace ServiceLib.Models.Dto; public class SemanticVersion { private readonly int major; private readonly int minor; private readonly int patch; private readonly string version; public SemanticVersion(int major, int minor, int patch) { this.major = major; this.minor = minor; this.patch = patch; version = $"{major}.{minor}.{patch}"; } public SemanticVersion(string? version) { try { if (string.IsNullOrEmpty(version)) { major = 0; minor = 0; patch = 0; return; } this.version = version.RemovePrefix('v'); var parts = this.version.Split('.'); if (parts.Length == 2) { major = int.Parse(parts.First()); minor = int.Parse(parts.Last()); patch = 0; } else if (parts.Length is 3 or 4) { major = int.Parse(parts[0]); minor = int.Parse(parts[1]); patch = int.Parse(parts[2]); } else { throw new ArgumentException("Invalid version string"); } } catch { major = 0; minor = 0; patch = 0; } } public override bool Equals(object? obj) { if (obj is SemanticVersion other) { return major == other.major && minor == other.minor && patch == other.patch; } else { return false; } } public override int GetHashCode() { return major.GetHashCode() ^ minor.GetHashCode() ^ patch.GetHashCode(); } /// /// Use ToVersionString(string? prefix) instead if possible. /// /// major.minor.patch public override string ToString() { return version; } public string ToVersionString(string? prefix = null) { if (prefix == null) { return version; } else { return $"{prefix}{version}"; } } public static bool operator ==(SemanticVersion v1, SemanticVersion v2) { return v1.Equals(v2); } public static bool operator !=(SemanticVersion v1, SemanticVersion v2) { return !v1.Equals(v2); } public static bool operator >=(SemanticVersion v1, SemanticVersion v2) { return v1.GreaterEquals(v2); } public static bool operator <=(SemanticVersion v1, SemanticVersion v2) { return v1.LessEquals(v2); } #region Private private bool GreaterEquals(SemanticVersion other) { if (major < other.major) { return false; } else if (major > other.major) { return true; } else { if (minor < other.minor) { return false; } else if (minor > other.minor) { return true; } else { if (patch < other.patch) { return false; } else if (patch > other.patch) { return true; } else { return true; } } } } private bool LessEquals(SemanticVersion other) { if (major < other.major) { return true; } else if (major > other.major) { return false; } else { if (minor < other.minor) { return true; } else if (minor > other.minor) { return false; } else { if (patch < other.patch) { return true; } else if (patch > other.patch) { return false; } else { return true; } } } } #endregion Private }