93 lines
1.4 KiB
Go
93 lines
1.4 KiB
Go
package version
|
|
|
|
import (
|
|
"strconv"
|
|
"strings"
|
|
)
|
|
|
|
const (
|
|
sectionMajor = 0
|
|
sectionMinor = 1
|
|
sectionPatch = 2
|
|
sectionExtension = 3
|
|
)
|
|
|
|
func MustParse(str string) *Version {
|
|
v, err := Parse(str)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
return v
|
|
}
|
|
|
|
func Parse(str string) (*Version, error) {
|
|
v := &Version{Text: string(str)}
|
|
|
|
if len(str) == 0 {
|
|
return nil, invalid(str)
|
|
}
|
|
|
|
section := sectionMajor
|
|
chars := []byte{}
|
|
|
|
commit := func() error {
|
|
if len(chars) == 0 {
|
|
return invalid(str)
|
|
}
|
|
|
|
if section < sectionExtension {
|
|
n, err := strconv.Atoi(string(chars))
|
|
if err != nil {
|
|
return invalid(str)
|
|
}
|
|
|
|
switch section {
|
|
case sectionMajor:
|
|
v.Major = n
|
|
case sectionMinor:
|
|
v.Minor = n
|
|
case sectionPatch:
|
|
v.Patch = n
|
|
}
|
|
} else {
|
|
v.Extension = string(chars)
|
|
}
|
|
|
|
chars = []byte{}
|
|
return nil
|
|
}
|
|
|
|
for i := 0; i < len(str); i++ {
|
|
c := str[i]
|
|
|
|
if i == 0 && strings.IndexByte("vV", c) > -1 {
|
|
continue
|
|
}
|
|
|
|
if section < sectionExtension {
|
|
if strings.IndexByte("0123456789", c) > -1 {
|
|
chars = append(chars, c)
|
|
} else {
|
|
if err := commit(); err != nil {
|
|
return nil, err
|
|
}
|
|
if c == '.' {
|
|
section++
|
|
} else {
|
|
section = sectionExtension
|
|
chars = append(chars, c)
|
|
}
|
|
}
|
|
} else {
|
|
chars = append(chars, c)
|
|
}
|
|
}
|
|
if len(chars) > 0 {
|
|
if err := commit(); err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
return v, nil
|
|
}
|