1 module armos.utils.semver;
2 
3 ///
4 struct SemVer{
5     ///
6     int major;
7     
8     ///
9     int minor;
10     
11     ///
12     int patch;
13     
14     ///
15     this(in string semver){
16         import std.algorithm;
17         import std.array;
18         import std.conv;
19         immutable digits = semver.split(".").map!(n => n.to!int).array;
20         major = digits[0];
21         minor = digits[1];
22         patch = digits[2];
23     }
24     
25     ///
26     this(in uint major, in uint minor, in uint patch){
27         this.major = major;
28         this.minor = minor;
29         this.patch = patch;
30     }
31     
32     ///
33     int opCmp(in SemVer rhs)const{
34         if(
35             this.major == rhs.major &&
36             this.minor == rhs.minor &&
37             this.patch == rhs.patch
38         ){
39             return 0;
40         }else if(this.major > rhs.major || 
41                  this.major == rhs.major && this.minor > rhs.minor ||
42                  this.major == rhs.major && this.minor == rhs.minor && this.patch > rhs.patch
43         ){
44             return 1;
45         }else{
46             return -1;
47         }
48     }
49     
50     ///
51     SemVer opBinary(string op)(in SemVer rhs){
52         static if (op == "+" || op == "-"){
53              return mixin("SemVer( this.major" ~ op ~ "rhs.major, this.minor" ~ op ~ "rhs.minor, this.patch" ~ op ~ "rhs.patch)");
54         }else{
55             static assert(0, "Operator "~op~" not implemented");
56         }
57     } 
58     
59     ///
60     string toString()const{
61         import std.algorithm;
62         import std.array;
63         import std.conv;
64         return [major, minor, patch].map!(n => n.to!string).join(".");
65     }
66 
67 }
68 
69 unittest{
70     assert(SemVer(1, 2, 3) == SemVer(1, 2, 3));
71     assert(SemVer(1, 2, 4) != SemVer(1, 2, 3));
72     
73     assert(SemVer(1, 2, 3) < SemVer(1, 2, 4));
74     assert(SemVer(1, 2, 4) > SemVer(1, 2, 3));
75     assert(SemVer(1, 3, 3) > SemVer(1, 2, 3));
76     assert(SemVer(2, 2, 3) > SemVer(1, 2, 3));
77     
78     assert(SemVer(1, 2, 3) >= SemVer(1, 2, 3));
79     assert(SemVer(1, 2, 3) <= SemVer(1, 2, 3));
80 }
81 
82 unittest{
83     //valid operators
84     assert(SemVer(1, 2, 3) + SemVer(1, 2, 3) == SemVer(2, 4, 6));
85     assert(SemVer(2, 3, 4) - SemVer(1, 2, 3) == SemVer(1, 1, 1));
86     
87     //invalid operators
88     assert(!__traits(compiles, {
89         auto v = SemVer(2, 3, 4) * SemVer(1, 2, 3);
90     }));
91     assert(!__traits(compiles, {
92         auto v = SemVer(2, 3, 4) / SemVer(1, 2, 3);
93     }));
94 }