SemVerComparer.cs 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. using System;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. namespace Artees.UnitySemVer
  5. {
  6. internal class SemVerComparer : IComparer<SemVer>
  7. {
  8. public int Compare(SemVer x, SemVer y)
  9. {
  10. if (ReferenceEquals(x, y)) return 0;
  11. if (ReferenceEquals(null, y)) return 1;
  12. if (ReferenceEquals(x, null)) return -1;
  13. var majorComparison = x.major.CompareTo(y.major);
  14. if (majorComparison != 0) return majorComparison;
  15. var minorComparison = x.minor.CompareTo(y.minor);
  16. if (minorComparison != 0) return minorComparison;
  17. var patchComparison = x.patch.CompareTo(y.patch);
  18. return patchComparison != 0 ? patchComparison : ComparePreReleaseVersions(x, y);
  19. }
  20. private static int ComparePreReleaseVersions(SemVer x, SemVer y)
  21. {
  22. if (IsPreRelease(x))
  23. {
  24. if (!IsPreRelease(y)) return -1;
  25. }
  26. else
  27. {
  28. return IsPreRelease(y) ? 1 : 0;
  29. }
  30. var xIdentifiers = x.preRelease.Split(SemVer.IdentifiersSeparator);
  31. var yIdentifiers = y.preRelease.Split(SemVer.IdentifiersSeparator);
  32. var length = Mathf.Min(xIdentifiers.Length, yIdentifiers.Length);
  33. for (var i = 0; i < length; i++)
  34. {
  35. var xIdentifier = xIdentifiers[i];
  36. var yIdentifier = yIdentifiers[i];
  37. if (Equals(xIdentifier, yIdentifier)) continue;
  38. return ComparePreReleaseIdentifiers(xIdentifier, yIdentifier);
  39. }
  40. return xIdentifiers.Length.CompareTo(yIdentifiers.Length);
  41. }
  42. private static bool IsPreRelease(SemVer semVer)
  43. {
  44. return !string.IsNullOrEmpty(semVer.preRelease);
  45. }
  46. private static int ComparePreReleaseIdentifiers(string xIdentifier, string yIdentifier)
  47. {
  48. var isXNumber = int.TryParse(xIdentifier, out var xNumber);
  49. var isYNumber = int.TryParse(yIdentifier, out var yNumber);
  50. if (!isXNumber)
  51. {
  52. const StringComparison comparison = StringComparison.Ordinal;
  53. return isYNumber ? 1 : string.Compare(xIdentifier, yIdentifier, comparison);
  54. }
  55. if (isYNumber)
  56. {
  57. return xNumber.CompareTo(yNumber);
  58. }
  59. return -1;
  60. }
  61. }
  62. }