SuffixVersion.cs 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6. namespace ClashDotNetFramework.Models.GitHubRelease
  7. {
  8. [Serializable]
  9. public struct SuffixVersion : ICloneable, IComparable, IComparable<SuffixVersion>, IEquatable<SuffixVersion>
  10. {
  11. public int Major { get; }
  12. public int Minor { get; }
  13. public int Patch { get; }
  14. public string PreRelease { get; }
  15. public int Build { get; }
  16. public SuffixVersion(int major, int minor, int patch, string preRelease, int build)
  17. {
  18. Major = major;
  19. Minor = minor;
  20. Patch = patch;
  21. PreRelease = preRelease;
  22. Build = build;
  23. }
  24. public SuffixVersion(Version version, string preRelease, int build)
  25. {
  26. Major = version.Major;
  27. Minor = version.Minor;
  28. Patch = version.Build;
  29. PreRelease = preRelease;
  30. Build = build;
  31. }
  32. public static SuffixVersion Parse(string input)
  33. {
  34. if (input.StartsWith("v"))
  35. {
  36. input = input.Substring(1, input.Length - 1);
  37. }
  38. var splitStr = input.Split('-');
  39. var dotNetVersion = Version.Parse(splitStr[0]);
  40. var preRelease = new StringBuilder();
  41. var build = 0;
  42. if (splitStr.Length > 1)
  43. foreach (var c in splitStr[1])
  44. if (int.TryParse(c.ToString(), out var n))
  45. build = build * 10 + n;
  46. else
  47. preRelease.Append(c);
  48. return new SuffixVersion(dotNetVersion, preRelease.ToString(), build);
  49. }
  50. public static bool TryParse(string input, out SuffixVersion result)
  51. {
  52. try
  53. {
  54. result = Parse(input);
  55. return true;
  56. }
  57. catch (Exception)
  58. {
  59. result = default;
  60. return false;
  61. }
  62. }
  63. public object Clone()
  64. {
  65. return new SuffixVersion(Major, Major, Patch, PreRelease, Build);
  66. }
  67. public int CompareTo(object obj)
  68. {
  69. if (obj is SuffixVersion version)
  70. return CompareTo(version);
  71. return -1;
  72. }
  73. /// <summary>
  74. /// </summary>
  75. /// <param name="other"></param>
  76. /// <returns>
  77. /// greater than 0 newer
  78. /// </returns>
  79. public int CompareTo(SuffixVersion other)
  80. {
  81. var majorComparison = Major.CompareTo(other.Major);
  82. if (majorComparison != 0)
  83. return majorComparison;
  84. var minorComparison = Minor.CompareTo(other.Minor);
  85. if (minorComparison != 0)
  86. return minorComparison;
  87. var patchComparison = Patch.CompareTo(other.Patch);
  88. if (patchComparison != 0)
  89. return patchComparison;
  90. if (PreRelease == string.Empty)
  91. return other.PreRelease == string.Empty ? 0 : 1;
  92. if (other.PreRelease == string.Empty)
  93. return -1;
  94. var suffixComparison = string.Compare(PreRelease, other.PreRelease, StringComparison.Ordinal);
  95. if (suffixComparison != 0)
  96. return suffixComparison;
  97. return Build.CompareTo(other.Build);
  98. }
  99. public bool Equals(SuffixVersion other)
  100. {
  101. return Major == other.Major && Minor == other.Minor && Patch == other.Patch && PreRelease == other.PreRelease && Build == other.Build;
  102. }
  103. public override bool Equals(object obj)
  104. {
  105. return obj is SuffixVersion other && Equals(other);
  106. }
  107. public override int GetHashCode()
  108. {
  109. unchecked
  110. {
  111. var hashCode = Major;
  112. hashCode = (hashCode * 397) ^ Minor;
  113. hashCode = (hashCode * 397) ^ Patch;
  114. hashCode = (hashCode * 397) ^ (PreRelease != null ? PreRelease.GetHashCode() : 0);
  115. hashCode = (hashCode * 397) ^ Build;
  116. return hashCode;
  117. }
  118. }
  119. public override string ToString()
  120. {
  121. return $"{Major}.{Minor}.{Patch}{(string.IsNullOrEmpty(PreRelease) ? "" : "-")}{PreRelease}{(Build == 0 ? "" : Build.ToString())}";
  122. }
  123. }
  124. }