Created
June 20, 2011 08:25
-
-
Save jpf91/1035294 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import std.datetime; | |
import std.array; | |
import std.conv; | |
import std.string; | |
import std.algorithm; | |
struct PackageVersion | |
{ | |
enum VersionType | |
{ | |
release, | |
prerelease, | |
snapshot | |
} | |
VersionType type; | |
uint[] baseVersion; | |
uint pre; | |
DateTime date; | |
this(uint[] ver) | |
{ | |
this.type = VersionType.release; | |
this.baseVersion = ver; | |
} | |
this(uint[] ver, uint preRel) | |
{ | |
this.type = VersionType.prerelease; | |
this.baseVersion = ver; | |
this.pre = preRel; | |
} | |
this(uint[] ver, DateTime snap, uint preRel = 0) | |
{ | |
this.type = VersionType.snapshot; | |
this.baseVersion = ver; | |
this.pre = preRel; | |
this.date = snap; | |
} | |
int opCmp(PackageVersion rhs) | |
{ | |
return compareVersion(this, rhs); | |
} | |
string toString() | |
{ | |
static string baseVerToString(uint[] basever) | |
{ | |
string result; | |
foreach(i, number; basever) | |
{ | |
result ~= to!string(number); | |
if(i != basever.length -1) | |
result ~= "."; | |
} | |
return result; | |
} | |
final switch(this.type) | |
{ | |
case VersionType.release: | |
return format("%s", baseVerToString(this.baseVersion)); | |
break; | |
case VersionType.prerelease: | |
return format("%s-pre%s", baseVerToString(this.baseVersion), this.pre); | |
break; | |
case VersionType.snapshot: | |
if(this.pre != 0) | |
return format("%s-pre%s snapshot-%s", baseVerToString(this.baseVersion), | |
this.pre, this.date.toSimpleString); | |
else | |
return format("%s snapshot-%s", baseVerToString(this.baseVersion), | |
this.date.toSimpleString); | |
break; | |
} | |
} | |
} | |
int compareBaseVer(const(uint[]) lhs, const(uint[]) rhs) | |
{ | |
foreach(i, number; lhs[0 .. min(lhs.length, rhs.length)]) | |
{ | |
if(number > rhs[i]) | |
return 1; | |
if(number < rhs[i]) | |
return -1; | |
} | |
if(lhs.length == rhs.length) | |
return 0; | |
if(lhs.length > rhs.length) | |
{ | |
foreach(number; lhs[rhs.length .. $]) | |
{ | |
if(number != 0) | |
return 1; | |
} | |
return 0; | |
} | |
if(lhs.length < rhs.length) | |
{ | |
foreach(number; rhs[lhs.length .. $]) | |
{ | |
if(number != 0) | |
return -1; | |
} | |
return 0; | |
} | |
assert(0); | |
} | |
unittest | |
{ | |
assert(compareBaseVer([1], [1]) == 0); | |
assert(compareBaseVer([0], [1]) == -1); | |
assert(compareBaseVer([1], [0]) == 1); | |
assert(compareBaseVer([1], [1, 0, 0, 0]) == 0); | |
assert(compareBaseVer([1, 0, 0, 1], [1]) == 1); | |
assert(compareBaseVer([1], [1, 0, 0, 0]) == 0); | |
assert(compareBaseVer([1], [1, 0, 0, 1]) == -1); | |
assert(compareBaseVer([1, 0, 0, 1], [1, 0, 0, 2]) == -1); | |
assert(compareBaseVer([1, 0, 0, 2], [1, 0, 0,1 ]) == 1); | |
assert(compareBaseVer([1, 1, 0, 1], [1, 0, 0, 2]) == 1); | |
assert(compareBaseVer([1, 0, 0, 2], [1, 1, 0,1 ]) == -1); | |
} | |
int coparePreRelease(uint[] lhs, uint lhsPre, uint[] rhs, uint rhsPre) | |
{ | |
int res = compareBaseVer(lhs, rhs); | |
if(res != 0) | |
return res; | |
if(lhsPre == rhsPre) | |
return 0; | |
if(lhsPre == 0) | |
return 1; | |
if(rhsPre == 0) | |
return -1; | |
if(lhsPre > rhsPre) | |
return 1; | |
if(lhsPre < rhsPre) | |
return -1; | |
return 0; | |
} | |
int compareSnapshot(uint[] lhs, uint lhsPre, DateTime lhsDate, uint[] rhs, | |
uint rhsPre, DateTime rhsDate) | |
{ | |
int res = coparePreRelease(lhs, lhsPre, rhs, rhsPre); | |
if(res != 0) | |
return res; | |
if(lhsDate > rhsDate) | |
return 1; | |
if(lhsDate < rhsDate) | |
return -1; | |
return 0; | |
} | |
int compareVersion(PackageVersion lhs, PackageVersion rhs) | |
{ | |
final switch(lhs.type) | |
{ | |
case PackageVersion.VersionType.release: | |
final switch(rhs.type) | |
{ | |
case PackageVersion.VersionType.release: | |
return compareBaseVer(lhs.baseVersion, rhs.baseVersion); | |
break; | |
case PackageVersion.VersionType.prerelease: | |
return coparePreRelease(lhs.baseVersion, 0, rhs.baseVersion, rhs.pre); | |
break; | |
case PackageVersion.VersionType.snapshot: | |
return compareSnapshot(lhs.baseVersion, 0, DateTime.min, | |
rhs.baseVersion, rhs.pre, rhs.date); | |
break; | |
} | |
break; | |
case PackageVersion.VersionType.prerelease: | |
final switch(rhs.type) | |
{ | |
case PackageVersion.VersionType.release: | |
return coparePreRelease(lhs.baseVersion, lhs.pre, rhs.baseVersion, 0); | |
break; | |
case PackageVersion.VersionType.prerelease: | |
return coparePreRelease(lhs.baseVersion, lhs.pre, rhs.baseVersion, rhs.pre); | |
break; | |
case PackageVersion.VersionType.snapshot: | |
return compareSnapshot(lhs.baseVersion, lhs.pre, DateTime.min, | |
rhs.baseVersion, rhs.pre, rhs.date); | |
break; | |
} | |
break; | |
case PackageVersion.VersionType.snapshot: | |
final switch(rhs.type) | |
{ | |
case PackageVersion.VersionType.release: | |
return compareSnapshot(lhs.baseVersion, lhs.pre, lhs.date, | |
rhs.baseVersion, 0, DateTime.min); | |
break; | |
case PackageVersion.VersionType.prerelease: | |
return compareSnapshot(lhs.baseVersion, lhs.pre, lhs.date, | |
rhs.baseVersion, rhs.pre, DateTime.min); | |
break; | |
case PackageVersion.VersionType.snapshot: | |
return compareSnapshot(lhs.baseVersion, lhs.pre, lhs.date, | |
rhs.baseVersion, rhs.pre, rhs.date); | |
break; | |
} | |
break; | |
} | |
} | |
import std.random; | |
import std.stdio; | |
void main() | |
{ | |
PackageVersion[] versions; | |
versions ~= PackageVersion([0,0,0,1]); | |
versions ~= PackageVersion([0,0,1,1], DateTime(2011, 06, 20, 0, 0, 0)); //snapshot | |
versions ~= PackageVersion([0,0,1,1], DateTime(2011, 06, 20, 1, 0, 0)); //snapshot | |
versions ~= PackageVersion([0,0,1,1], 1); //alpha1 | |
versions ~= PackageVersion([0,0,1,1], DateTime(2011, 06, 20, 1, 0, 0), 1); //snapshot based on alpha1 | |
versions ~= PackageVersion([0,0,1,1], 2); //alpha2 | |
versions ~= PackageVersion([0,0,1,1], 3); //beta1 | |
versions ~= PackageVersion([0,0,1,1], DateTime(2011, 06, 20, 1, 0, 1), 3); //snapshot | |
versions ~= PackageVersion([0,0,1,1], DateTime(2011, 06, 20, 1, 0, 2), 3); //snapshot | |
versions ~= PackageVersion([0,0,1,1], DateTime(2011, 06, 20, 1, 0, 3), 3); //snapshot | |
versions ~= PackageVersion([0,0,2,0], 1); //alpha1 | |
versions ~= PackageVersion([0,0,2,0], 2); //alpha2 | |
versions ~= PackageVersion([0,0,2,0], DateTime(2011, 06, 20, 1, 0, 10), 2); //snapshot | |
versions ~= PackageVersion([0,0,2,0], DateTime(2011, 06, 20, 1, 0, 11), 2); //snapshot | |
versions ~= PackageVersion([0,0,1,1], 4); //rc1 | |
versions ~= PackageVersion([0,0,1,1], DateTime(2011, 06, 20, 1, 0, 20), 4); //snapshot | |
versions ~= PackageVersion([0,0,1,1], DateTime(2011, 06, 20, 1, 0, 21), 4); //snapshot | |
versions ~= PackageVersion([0,0,1,1]); //final | |
randomShuffle(versions); | |
sort!("a < b")(versions); | |
foreach(ver; versions) | |
writeln(ver); | |
} |
Damn, just noted it sorts in the wrong direction :fp I guess I should have looked up the opCmp documentation...
EDIT: fixed
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Output: