blob: d3b0051b6b6f71a7ccd328f4ab9f131c493b39d1 [file] [log] [blame]
// Copyright 2019 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package stableversion
import (
"fmt"
"regexp"
"strconv"
)
// findMatchMap takes a regexp and a string and returns a map
// associating the named capture groups in the regexp to their values.
//
// It is intended to be used primarily with regexps such as the one below.
//
// regexp.MustCompile(`\AR(?P<release>[0-9]+)-(?P<tip>[0-9]+)\.(?P<branch>[0-9]+)\.(?P<branchbranch>[0-9]+)\z`)
//
// The regexp above only has named capture groups and always matches exactly once because of the \A and \z anchors.
// The intended use case is to use a regexp such as the one above as a blueprint for converting a string into a map
// from strings to strings.
func findMatchMap(r *regexp.Regexp, s string) (map[string]string, error) {
if r == nil {
return nil, fmt.Errorf("*regexp cannot be nil")
}
out := make(map[string]string)
matchNames := r.SubexpNames()
matchValues := r.FindStringSubmatch(s)
if len(matchNames) != len(matchValues) {
return nil, fmt.Errorf("mismatch between len(matchNames) (%d) and len(matchValues) (%d)", len(matchNames), len(matchValues))
}
for i, name := range matchNames {
if name != "" {
out[name] = matchValues[i]
}
}
return out, nil
}
func asInt(s string) int {
i64, err := strconv.ParseInt(s, 10, 32)
if err != nil {
return 0
}
return int(i64)
}
func parseInt(s string) (int, error) {
i64, err := strconv.ParseInt(s, 10, 32)
if err != nil {
return 0, err
}
return int(i64), nil
}
func extractInt(m map[string]string, k string) (int, error) {
if value, ok := m[k]; ok {
if value == "" {
return 0, fmt.Errorf("%s cannot be empty", k)
}
return parseInt(value)
}
return 0, fmt.Errorf("key %s must be present", k)
}
func extractString(m map[string]string, k string) (string, error) {
if value, ok := m[k]; ok {
return value, nil
}
return "", fmt.Errorf("key %s must be present", k)
}