class Version implements Comparable<Version> {
factory Version(int major, int minor, int patch, {String text}) {
if (text == null) {
text = major == null ? '0' : '$major';
if (minor != null)
text = '$text.$minor';
if (patch != null)
text = '$text.$patch';
}
return Version._(major ?? 0, minor ?? 0, patch ?? 0, text);
}
Version._(this.major, this.minor, this.patch, this._text) {
if (major < 0)
throw ArgumentError('Major version must be non-negative.');
if (minor < 0)
throw ArgumentError('Minor version must be non-negative.');
if (patch < 0)
throw ArgumentError('Patch version must be non-negative.');
}
factory Version.parse(String text) {
final Match match = versionPattern.firstMatch(text ?? '');
if (match == null) {
return null;
}
try {
final int major = int.parse(match[1] ?? '0');
final int minor = int.parse(match[3] ?? '0');
final int patch = int.parse(match[5] ?? '0');
return Version._(major, minor, patch, text);
} on FormatException {
return null;
}
}
static Version primary(List<Version> versions) {
Version primary;
for (Version version in versions) {
if (primary == null || (version > primary)) {
primary = version;
}
}
return primary;
}
static Version get unknown => Version(0, 0, 0, text: 'unknown');
final int major;
final int minor;
final int patch;
final String _text;
static final RegExp versionPattern =
RegExp(r'^(\d+)(\.(\d+)(\.(\d+))?)?');
@override
bool operator ==(dynamic other) {
if (other is! Version)
return false;
return major == other.major && minor == other.minor && patch == other.patch;
}
@override
int get hashCode => major ^ minor ^ patch;
bool operator <(Version other) => compareTo(other) < 0;
bool operator >(Version other) => compareTo(other) > 0;
bool operator <=(Version other) => compareTo(other) <= 0;
bool operator >=(Version other) => compareTo(other) >= 0;
@override
int compareTo(Version other) {
if (major != other.major)
return major.compareTo(other.major);
if (minor != other.minor)
return minor.compareTo(other.minor);
return patch.compareTo(other.patch);
}
@override
String toString() => _text;
}