@@ -22,15 +22,20 @@ func MustParse(inVersion string) *Version {
22
22
}
23
23
24
24
// Parse parse a version string
25
- func Parse (inVersioin string ) (* Version , error ) {
25
+ func Parse (inVersion string ) (* Version , error ) {
26
26
result := & Version {
27
27
major : empty [:],
28
28
minor : empty [:],
29
29
patch : empty [:],
30
30
}
31
+ if err := parseInto ([]byte (inVersion ), result ); err != nil {
32
+ return nil , err
33
+ }
34
+ return result , nil
35
+ }
31
36
37
+ func parseInto (in []byte , result * Version ) error {
32
38
// Setup parsing harness
33
- in := []byte (inVersioin )
34
39
inLen := len (in )
35
40
currIdx := - 1
36
41
var curr byte
@@ -51,28 +56,28 @@ func Parse(inVersioin string) (*Version, error) {
51
56
52
57
// Parse major
53
58
if ! next () {
54
- return result , nil // empty version
59
+ return nil // empty version
55
60
}
56
61
if ! numeric [curr ] {
57
- return nil , fmt .Errorf ("no major version found" )
62
+ return fmt .Errorf ("no major version found" )
58
63
}
59
64
if curr == '0' {
60
65
result .major = in [0 :1 ] // 0
61
66
if ! next () {
62
- return result , nil
67
+ return nil
63
68
}
64
69
if numeric [curr ] {
65
- return nil , fmt .Errorf ("major version must not be prefixed with zero" )
70
+ return fmt .Errorf ("major version must not be prefixed with zero" )
66
71
}
67
72
if ! versionSeparator [curr ] {
68
- return nil , fmt .Errorf ("invalid major version separator '%c'" , curr )
73
+ return fmt .Errorf ("invalid major version separator '%c'" , curr )
69
74
}
70
75
// Fallthrough and parse next element
71
76
} else {
72
77
for {
73
78
if ! next () {
74
79
result .major = in [0 :currIdx ]
75
- return result , nil
80
+ return nil
76
81
}
77
82
if numeric [curr ] {
78
83
continue
@@ -81,33 +86,33 @@ func Parse(inVersioin string) (*Version, error) {
81
86
result .major = in [0 :currIdx ]
82
87
break
83
88
}
84
- return nil , fmt .Errorf ("invalid major version separator '%c'" , curr )
89
+ return fmt .Errorf ("invalid major version separator '%c'" , curr )
85
90
}
86
91
}
87
92
88
93
// Parse minor
89
94
if curr == '.' {
90
95
if ! next () || ! numeric [curr ] {
91
- return nil , fmt .Errorf ("no minor version found" )
96
+ return fmt .Errorf ("no minor version found" )
92
97
}
93
98
if curr == '0' {
94
99
result .minor = in [currIdx : currIdx + 1 ] // x.0
95
100
if ! next () {
96
- return result , nil
101
+ return nil
97
102
}
98
103
if numeric [curr ] {
99
- return nil , fmt .Errorf ("minor version must not be prefixed with zero" )
104
+ return fmt .Errorf ("minor version must not be prefixed with zero" )
100
105
}
101
106
if ! versionSeparator [curr ] {
102
- return nil , fmt .Errorf ("invalid minor version separator '%c'" , curr )
107
+ return fmt .Errorf ("invalid minor version separator '%c'" , curr )
103
108
}
104
109
// Fallthrough and parse next element
105
110
} else {
106
111
minorIdx := currIdx
107
112
for {
108
113
if ! next () {
109
114
result .minor = in [minorIdx :currIdx ]
110
- return result , nil
115
+ return nil
111
116
}
112
117
if numeric [curr ] {
113
118
continue
@@ -116,34 +121,34 @@ func Parse(inVersioin string) (*Version, error) {
116
121
result .minor = in [minorIdx :currIdx ]
117
122
break
118
123
}
119
- return nil , fmt .Errorf ("invalid minor version separator '%c'" , curr )
124
+ return fmt .Errorf ("invalid minor version separator '%c'" , curr )
120
125
}
121
126
}
122
127
}
123
128
124
129
// Parse patch
125
130
if curr == '.' {
126
131
if ! next () || ! numeric [curr ] {
127
- return nil , fmt .Errorf ("no patch version found" )
132
+ return fmt .Errorf ("no patch version found" )
128
133
}
129
134
if curr == '0' {
130
135
result .patch = in [currIdx : currIdx + 1 ] // x.y.0
131
136
if ! next () {
132
- return result , nil
137
+ return nil
133
138
}
134
139
if numeric [curr ] {
135
- return nil , fmt .Errorf ("patch version must not be prefixed with zero" )
140
+ return fmt .Errorf ("patch version must not be prefixed with zero" )
136
141
}
137
142
if ! versionSeparator [curr ] {
138
- return nil , fmt .Errorf ("invalid patch version separator '%c'" , curr )
143
+ return fmt .Errorf ("invalid patch version separator '%c'" , curr )
139
144
}
140
145
// Fallthrough and parse next element
141
146
} else {
142
147
patchIdx := currIdx
143
148
for {
144
149
if ! next () {
145
150
result .patch = in [patchIdx :currIdx ]
146
- return result , nil
151
+ return nil
147
152
}
148
153
if numeric [curr ] {
149
154
continue
@@ -152,7 +157,7 @@ func Parse(inVersioin string) (*Version, error) {
152
157
result .patch = in [patchIdx :currIdx ]
153
158
break
154
159
}
155
- return nil , fmt .Errorf ("invalid patch version separator '%c'" , curr )
160
+ return fmt .Errorf ("invalid patch version separator '%c'" , curr )
156
161
}
157
162
}
158
163
}
@@ -176,15 +181,15 @@ func Parse(inVersioin string) (*Version, error) {
176
181
for {
177
182
if hasNext := next (); ! hasNext || curr == '.' || curr == '+' {
178
183
if prereleaseIdx == currIdx {
179
- return nil , fmt .Errorf ("empty prerelease not allowed" )
184
+ return fmt .Errorf ("empty prerelease not allowed" )
180
185
}
181
186
if zeroPrefix && ! alphaIdentifier && currIdx - prereleaseIdx > 1 {
182
- return nil , fmt .Errorf ("numeric prerelease must not be prefixed with zero" )
187
+ return fmt .Errorf ("numeric prerelease must not be prefixed with zero" )
183
188
}
184
189
result .prerelases = append (result .prerelases , in [prereleaseIdx :currIdx ])
185
190
result .numericPrereleases = append (result .numericPrereleases , ! alphaIdentifier )
186
191
if ! hasNext {
187
- return result , nil
192
+ return nil
188
193
}
189
194
if curr == '+' {
190
195
break
@@ -207,7 +212,7 @@ func Parse(inVersioin string) (*Version, error) {
207
212
alphaIdentifier = true
208
213
continue
209
214
}
210
- return nil , fmt .Errorf ("invalid prerelease separator: '%c'" , curr )
215
+ return fmt .Errorf ("invalid prerelease separator: '%c'" , curr )
211
216
}
212
217
}
213
218
@@ -226,11 +231,11 @@ func Parse(inVersioin string) (*Version, error) {
226
231
for {
227
232
if hasNext := next (); ! hasNext || curr == '.' {
228
233
if buildIdx == currIdx {
229
- return nil , fmt .Errorf ("empty build tag not allowed" )
234
+ return fmt .Errorf ("empty build tag not allowed" )
230
235
}
231
236
result .builds = append (result .builds , in [buildIdx :currIdx ])
232
237
if ! hasNext {
233
- return result , nil
238
+ return nil
234
239
}
235
240
236
241
// Multiple builds
@@ -240,8 +245,8 @@ func Parse(inVersioin string) (*Version, error) {
240
245
if identifier [curr ] {
241
246
continue
242
247
}
243
- return nil , fmt .Errorf ("invalid separator for builds: '%c'" , curr )
248
+ return fmt .Errorf ("invalid separator for builds: '%c'" , curr )
244
249
}
245
250
}
246
- return nil , fmt .Errorf ("invalid separator: '%c'" , curr )
251
+ return fmt .Errorf ("invalid separator: '%c'" , curr )
247
252
}
0 commit comments