Parse returns a Version struct filled with the epoch, version and revision specified in input. It verifies the version string as a whole, just like dpkg(1), and even returns roughly the same error messages.
(input string)
| 125 | // specified in input. It verifies the version string as a whole, just like |
| 126 | // dpkg(1), and even returns roughly the same error messages. |
| 127 | func Parse(input string) (Version, error) { |
| 128 | result := Version{} |
| 129 | trimmed := strings.TrimSpace(input) |
| 130 | if trimmed == "" { |
| 131 | return result, fmt.Errorf("version string is empty") |
| 132 | } |
| 133 | |
| 134 | if strings.IndexFunc(trimmed, unicode.IsSpace) != -1 { |
| 135 | return result, fmt.Errorf("version string has embedded spaces") |
| 136 | } |
| 137 | |
| 138 | colon := strings.Index(trimmed, ":") |
| 139 | if colon != -1 { |
| 140 | epoch, err := strconv.ParseInt(trimmed[:colon], 10, 64) |
| 141 | if err != nil { |
| 142 | return result, fmt.Errorf("epoch: %v", err) |
| 143 | } |
| 144 | if epoch < 0 { |
| 145 | return result, fmt.Errorf("epoch in version is negative") |
| 146 | } |
| 147 | result.Epoch = uint(epoch) |
| 148 | } |
| 149 | |
| 150 | result.Version = trimmed[colon+1:] |
| 151 | if len(result.Version) == 0 { |
| 152 | return result, fmt.Errorf("nothing after colon in version number") |
| 153 | } |
| 154 | if hyphen := strings.LastIndex(result.Version, "-"); hyphen != -1 { |
| 155 | result.Revision = result.Version[hyphen+1:] |
| 156 | result.Version = result.Version[:hyphen] |
| 157 | } |
| 158 | |
| 159 | if len(result.Version) > 0 && !unicode.IsDigit(rune(result.Version[0])) { |
| 160 | return result, fmt.Errorf("version number does not start with digit") |
| 161 | } |
| 162 | |
| 163 | if strings.IndexFunc(result.Version, func(c rune) bool { |
| 164 | return !cisdigit(c) && !cisalpha(c) && c != '.' && c != '-' && c != '+' && c != '~' && c != ':' |
| 165 | }) != -1 { |
| 166 | return result, fmt.Errorf("invalid character in version number") |
| 167 | } |
| 168 | |
| 169 | if strings.IndexFunc(result.Revision, func(c rune) bool { |
| 170 | return !cisdigit(c) && !cisalpha(c) && c != '.' && c != '+' && c != '~' |
| 171 | }) != -1 { |
| 172 | return result, fmt.Errorf("invalid character in revision number") |
| 173 | } |
| 174 | |
| 175 | return result, nil |
| 176 | } |
| 177 | |
| 178 | // vim:ts=4:sw=4:noexpandtab |