1 /*
2  * This file is part of gir-to-d.
3  *
4  * gir-to-d is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU Lesser General Public License
6  * as published by the Free Software Foundation, either version 3
7  * of the License, or (at your option) any later version.
8  *
9  * gir-to-d is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public License
15  * along with gir-to-d.  If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 module gtd.GirVersion;
19 
20 import std.array;
21 import std.conv;
22 import std.format;
23 
24 struct GirVersion
25 {
26 	uint major;
27 	uint minor;
28 	uint micro;
29 
30 	this(string _version)
31 	{
32 		parse(_version);
33 	}
34 
35 	this(uint major, uint minor, uint micro = 0)
36 	{
37 		this.major = major;
38 		this.minor = minor;
39 		this.micro = micro;
40 	}
41 
42 	void parse(string _version)
43 	{
44 		string[] parts = split(_version, ".");
45 
46 		if ( parts.length >= 1 && !parts[0].empty )
47 			major = to!uint(parts[0]);
48 		if ( parts.length >= 2 && !parts[1].empty )
49 			minor = to!uint(parts[1]);
50 		if ( parts.length >= 3 && !parts[2].empty )
51 			micro = to!uint(parts[2]);
52 	}
53 
54 	string toString() const
55 	{
56 		return format("%s.%s.%s", major, minor, micro);
57 	}
58 
59 	void toString(scope void delegate(const(char)[]) sink) const
60     {
61 		sink(to!string(major));
62 		sink(".");
63 		sink(to!string(minor));
64 		sink(".");
65 		sink(to!string(micro));
66 	}
67 
68 	bool opEquals()(auto ref const GirVersion _version) const
69 	{
70 		if ( major != _version.major )
71 			return false;
72 		else if ( minor != _version.minor )
73 			return false;
74 		else if ( micro != _version.micro )
75 			return false;
76 
77 		return true;
78 	}
79 
80 	bool opEquals()(auto ref string _version) const
81 	{
82 		string[] parts = split(_version, ".");
83 
84 		if ( parts.length >= 1 && !parts[0].empty )
85 		{
86 			uint maj = to!uint(parts[0]);
87 
88 			if ( major != maj )
89 				return false;
90 		}
91 		if ( parts.length >= 2 && !parts[1].empty )
92 		{
93 			uint min = to!uint(parts[1]);
94 
95 			if ( minor != min )
96 				return false;
97 		}
98 		if ( parts.length >= 3 && !parts[2].empty )
99 		{
100 			uint mic = to!uint(parts[2]);
101 
102 			if ( micro != mic )
103 				return false;
104 		}
105 
106 		return true;
107 	}
108 
109 	int opCmp()(auto ref const GirVersion _version) const
110 	{
111 		if ( major != _version.major )
112 			return major - _version.major;
113 		else if ( minor != _version.minor )
114 			return minor - _version.minor;
115 
116 		return micro - _version.micro;
117 	}
118 
119 	int opCmp()(auto ref string _version) const
120 	{
121 		string[] parts = split(_version, ".");
122 
123 		if ( parts.length >= 1 && !parts[0].empty )
124 		{
125 			uint maj = to!uint(parts[0]);
126 
127 			if ( major != maj )
128 				return major - maj;
129 		}
130 		if ( parts.length >= 2 && !parts[1].empty )
131 		{
132 			uint min = to!uint(parts[1]);
133 
134 			if ( minor != min )
135 				return minor - min;
136 		}
137 		if ( parts.length >= 3 && !parts[2].empty )
138 		{
139 			uint mic = to!uint(parts[2]);
140 
141 			return micro - mic;
142 		}
143 
144 		return 0;
145 	}
146 }
147 
148 unittest
149 {
150 	auto v1 = GirVersion("1.2.3");
151 	auto v2 = GirVersion(2, 3);
152 
153 	assert(v1.minor == 2);
154 	assert(v1 < v2);
155 	assert(v2 == GirVersion("2.3"));
156 	assert(v2 > GirVersion("1.2.3"));
157 
158 	assert(v2 == "2.3");
159 	assert(v2 > "1.1.2");
160 	assert(v2 < "3.4");
161 	assert(v2 >= "2.3");
162 }