OpenContacts/lib/models/sem_ver.dart

80 lines
2.3 KiB
Dart
Raw Normal View History

class SemVer {
static final RegExp _versionMatcher = RegExp(r"^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$");
2023-10-12 13:17:53 -04:00
static final RegExp _characterFilter = RegExp(r"^[a-zA-Z]+");
final int major;
final int minor;
final int patch;
2023-10-12 13:17:53 -04:00
final String? label;
2023-10-12 13:17:53 -04:00
SemVer({required this.major, required this.minor, required this.patch, this.label});
factory SemVer.fromString(String str) {
str = str.replaceAll(_characterFilter, "");
final match = _versionMatcher.firstMatch(str);
if (match == null || match.group(1) == null) {
throw "Invalid version format";
}
return SemVer(
major: int.parse(match.group(1)!),
minor: int.parse(match.group(2) ?? "0"),
patch: int.parse(match.group(3) ?? "0"),
2023-10-12 13:17:53 -04:00
label: match.group(4),
);
}
factory SemVer.zero() {
return SemVer(major: 0, minor: 0, patch: 0);
}
factory SemVer.max() {
//Chosen because it is larger than any version this app will ever see but small enough to not look bad when displayed as text
const max = 999;
return SemVer(major: max, minor: max, patch: max);
}
bool get isZero => major == 0 && minor == 0 && patch == 0;
bool get isNotZero => !isZero;
@override
String toString() {
2023-10-12 13:17:53 -04:00
return "$major.$minor.$patch${label == null ? "" : "-$label"}";
}
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is SemVer &&
runtimeType == other.runtimeType &&
major == other.major &&
minor == other.minor &&
2023-10-12 13:17:53 -04:00
patch == other.patch &&
label == other.label;
@override
2023-10-12 13:17:53 -04:00
int get hashCode => major.hashCode ^ minor.hashCode ^ patch.hashCode ^ label.hashCode;
bool operator >(SemVer other) {
if (major > other.major || (major == other.major && minor > other.minor) || (major == other.major && minor == other.minor && patch > other.patch)) {
return true;
}
return false;
}
bool operator >=(SemVer other) {
if (this == other) return true;
return this > other;
}
bool operator <(SemVer other) {
return !(this > other);
}
bool operator <=(SemVer other) {
if (this == other) return true;
return this < other;
}
}