version.dart 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. class Version implements Comparable<Version> {
  2. final int major;
  3. final int minor;
  4. final int? build;
  5. final int? revision;
  6. Version(
  7. this.major,
  8. this.minor, [
  9. this.build,
  10. this.revision,
  11. ]);
  12. Version incrementMajor() => Version(major + 1, 0);
  13. Version incrementMinor() => Version(major, minor + 1);
  14. Version incrementBuild() => Version(major, minor, (build ?? 0) + 1);
  15. Version incrementRevision() =>
  16. Version(major, minor, build, (revision ?? 0) + 1);
  17. static Version parse(String input) {
  18. final str = input.trim();
  19. if (str.isEmpty) {
  20. throw const FormatException("Cannot parse empty string into version.");
  21. }
  22. final segments = str.split('.');
  23. if (segments.length < 2) {
  24. throw const FormatException(
  25. "Format error: major and minor are required.");
  26. }
  27. if (segments.any((e) => !_isIntger(e))) {
  28. throw const FormatException("Format error: segment can only be intger.");
  29. }
  30. final len = segments.length;
  31. int _major = int.parse(segments[0]);
  32. int _minor = int.parse(segments[1]);
  33. int? _build;
  34. int? _revison;
  35. if (len > 2) _build = int.parse(segments[2]);
  36. if (len > 3) _revison = int.parse(segments[3]);
  37. return Version(_major, _minor, _build, _revison);
  38. }
  39. @override
  40. int compareTo(Version? other) {
  41. if (other == null) {
  42. throw ArgumentError.notNull("other");
  43. }
  44. return _compare(this, other);
  45. }
  46. @override
  47. String toString() {
  48. final _build = build ?? (revision == null ? null : 0);
  49. return <int?>[major, minor, _build, revision]
  50. .where((e) => e != null)
  51. .join('.');
  52. }
  53. @override
  54. bool operator ==(Object other) =>
  55. other is Version && _compare(this, other) == 0;
  56. bool operator <(dynamic o) => o is Version && _compare(this, o) < 0;
  57. bool operator <=(dynamic o) => o is Version && _compare(this, o) <= 0;
  58. bool operator >(dynamic o) => o is Version && _compare(this, o) > 0;
  59. bool operator >=(dynamic o) => o is Version && _compare(this, o) >= 0;
  60. @override
  61. int get hashCode => toString().hashCode;
  62. static int _compare(Version? a, Version? b) {
  63. if (a == null) {
  64. throw ArgumentError.notNull("a");
  65. }
  66. if (b == null) {
  67. throw ArgumentError.notNull("b");
  68. }
  69. if (a.major > b.major) return 1;
  70. if (a.major < b.major) return -1;
  71. if (a.minor > b.minor) return 1;
  72. if (a.minor < b.minor) return -1;
  73. if (b.build != null) {
  74. if (a.build != null) {
  75. if (a.build! > b.build!) return 1;
  76. if (a.build! < b.build!) return -1;
  77. } else {
  78. if (b.build! > 0 && b.revision != null && b.revision! > 0) {
  79. return -1;
  80. }
  81. }
  82. }
  83. if (b.revision != null) {
  84. if (a.revision != null) {
  85. if (a.revision! > b.revision!) return 1;
  86. if (a.revision! < b.revision!) return -1;
  87. } else {
  88. if (b.revision! > 0) {
  89. return -1;
  90. }
  91. }
  92. }
  93. return 0;
  94. }
  95. static bool _isIntger(String? s) {
  96. if (s == null) {
  97. return false;
  98. }
  99. return int.tryParse(s) != null;
  100. }
  101. }