@@ -47,32 +47,47 @@ struct SemVer {
4747 * Throws: SemVerException if there is any syntax errors.
4848 */
4949 pure this (string i) {
50- import std.string : indexOf, isNumeric;
50+ import std.string : isNumeric;
5151 import std.conv : to;
5252
53- auto MajorDot = indexOf(i, ' .' , 0 );
54- auto MinorDot = indexOf(i, ' .' , MajorDot + 1 );
55- auto PreReleaseStart = indexOf(i, ' -' , MinorDot + 1 );
56- auto BuildStart = indexOf(i, ' +' , PreReleaseStart + 1 );
53+ size_t MajorDot, MinorDot, PreReleaseStart, BuildStart;
54+
55+ for (size_t count = 0 ; count < i.length; count++ ) {
56+ switch (i[count]) {
57+ case ' .' :
58+ if (! MajorDot) {
59+ MajorDot = count;
60+ break ;
61+ }
62+ if (! MinorDot)
63+ MinorDot = count;
64+ break ;
65+ case ' -' :
66+ if (! BuildStart && ! PreReleaseStart)
67+ PreReleaseStart = count;
68+ break ;
69+ case ' +' :
70+ BuildStart = count;
71+ break ;
72+ default : break ;
73+ }
74+ }
5775
58- if ((MajorDot == - 1 ) || (MinorDot == - 1 )) {
59- // If there is no 2 dots - this is not complete semver.
60- throw new SemVerException(" There is no major, minor or patch" );
61- } else if (MajorDot < 1 ) {
76+ if (MajorDot == 0 ) {
6277 // If first symbol is a dot, there is no Major.
6378 throw new SemVerException(" There is no major version number" );
64- } else if (( MinorDot < 1 ) || (MinorDot - MajorDot < 2 )) {
79+ } else if (! MinorDot || (MinorDot - MajorDot < 2 )) {
6580 // If there is nothing between MajorDot and MinorDot.
6681 throw new SemVerException(" There is no minor version number" );
6782 } else if (
68- (( PreReleaseStart < 1 ) && (i.length - MinorDot < 2 )) ||
69- (( PreReleaseStart >= 0 ) && (PreReleaseStart - MinorDot < 2 ))) {
83+ (! PreReleaseStart && (i.length - MinorDot < 2 )) ||
84+ (! PreReleaseStart && (PreReleaseStart - MinorDot < 2 ))) {
7085 // There is no Patch, if there is nothing after MinorDot.
7186 // and string end or `-`.
7287 throw new SemVerException(" There is no patch version number" );
7388 } else if (
74- (( BuildStart < 1 ) && (i.length - PreReleaseStart < 2 )) ||
75- ((BuildStart >= 0 ) && (BuildStart - PreReleaseStart < 2 ))) {
89+ (! BuildStart && (i.length - PreReleaseStart < 2 )) ||
90+ ((BuildStart > 0 ) && (BuildStart - PreReleaseStart < 2 ))) {
7691 // There is nothing in PreRelease, if nothing follow `-` .
7792 throw new SemVerException(" There is no prerelease version string" );
7893 } else if (i.length - BuildStart < 2 ) {
@@ -86,7 +101,7 @@ struct SemVer {
86101
87102 Major = to! size_t (i[0 .. MajorDot]);
88103 } else {
89- throw new SemVerException(" There is a non-number characters in major" );
104+ throw new SemVerException(" There is a non-number in major" );
90105 }
91106
92107 if (isNumeric(i[MajorDot+ 1 .. MinorDot])) {
@@ -95,10 +110,10 @@ struct SemVer {
95110
96111 Minor = to! size_t (i[MajorDot+ 1 .. MinorDot]);
97112 } else {
98- throw new SemVerException(" There is a non-number characters in minor" );
113+ throw new SemVerException(" There is a non-number in minor" );
99114 }
100115
101- if (PreReleaseStart != - 1 ) {
116+ if (PreReleaseStart) {
102117 if (isNumeric(i[MinorDot+ 1 .. PreReleaseStart])) {
103118 if ((PreReleaseStart - MinorDot > 2 ) && (to! size_t (i[MinorDot+ 1 .. MinorDot+ 2 ]) == 0 ))
104119 throw new SemVerException(" Patch cannot begin with '0'" );
@@ -107,14 +122,14 @@ struct SemVer {
107122 } else {
108123 throw new SemVerException(" There is a non-number in patch" );
109124 }
110- if (BuildStart != - 1 ) {
125+ if (BuildStart) {
111126 PreRelease = i[PreReleaseStart+ 1 .. BuildStart];
112127 Build = i[BuildStart+ 1 .. $];
113128 } else {
114129 PreRelease = i[PreReleaseStart+ 1 .. $];
115130 }
116131 } else {
117- if (BuildStart != - 1 ) {
132+ if (BuildStart) {
118133 if (isNumeric(i[MinorDot+ 1 .. BuildStart])) {
119134 if ((BuildStart - MinorDot > 2 ) && (to! size_t (i[MinorDot+ 1 .. MinorDot+ 2 ]) == 0 ))
120135 throw new SemVerException(" Patch cannot begin with '0'" );
0 commit comments