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 }