зеркало из https://github.com/github/vitess-gh.git
90 строки
2.0 KiB
Go
90 строки
2.0 KiB
Go
// Package flagutil contains flags that parse string lists and string
|
|
// maps.
|
|
package flagutil
|
|
|
|
import (
|
|
_ "flag"
|
|
"sort"
|
|
"strings"
|
|
)
|
|
|
|
// StringListValue is a []string flag that accepts a comma separated
|
|
// list of elements. To include an element containing a comma, quote
|
|
// it with a backslash '\'.
|
|
type StringListValue []string
|
|
|
|
func (value StringListValue) Get() interface{} {
|
|
return []string(value)
|
|
}
|
|
|
|
func parseListWithEscapes(v string, delimiter rune) (value []string) {
|
|
var escaped, lastWasDelimiter bool
|
|
var current []rune
|
|
|
|
for _, r := range v {
|
|
lastWasDelimiter = false
|
|
if !escaped {
|
|
switch r {
|
|
case delimiter:
|
|
value = append(value, string(current))
|
|
current = nil
|
|
lastWasDelimiter = true
|
|
continue
|
|
case '\\':
|
|
escaped = true
|
|
continue
|
|
}
|
|
}
|
|
escaped = false
|
|
current = append(current, r)
|
|
}
|
|
if len(current) != 0 || lastWasDelimiter {
|
|
value = append(value, string(current))
|
|
}
|
|
return value
|
|
}
|
|
|
|
func (value *StringListValue) Set(v string) error {
|
|
*value = parseListWithEscapes(v, ',')
|
|
return nil
|
|
}
|
|
|
|
func (value StringListValue) String() string {
|
|
parts := make([]string, len(value))
|
|
for i, v := range value {
|
|
parts[i] = strings.Replace(strings.Replace(v, "\\", "\\\\", -1), ",", `\,`, -1)
|
|
}
|
|
return strings.Join(parts, ",")
|
|
|
|
}
|
|
|
|
// StringMapValue is a map[string]string flag. It accepts a
|
|
// comma-separated list of key value pairs, of the form key:value. The
|
|
// keys cannot contain colons.
|
|
type StringMapValue map[string]string
|
|
|
|
func (value *StringMapValue) Set(v string) error {
|
|
dict := make(map[string]string)
|
|
pairs := parseListWithEscapes(v, ',')
|
|
for _, pair := range pairs {
|
|
parts := strings.SplitN(pair, ":", 2)
|
|
dict[parts[0]] = parts[1]
|
|
}
|
|
*value = dict
|
|
return nil
|
|
}
|
|
|
|
func (value StringMapValue) Get() interface{} {
|
|
return map[string]string(value)
|
|
}
|
|
|
|
func (value StringMapValue) String() string {
|
|
parts := make([]string, 0)
|
|
for k, v := range value {
|
|
parts = append(parts, k+":"+strings.Replace(v, ",", `\,`, -1))
|
|
}
|
|
// Generate the string deterministically.
|
|
sort.Strings(parts)
|
|
return strings.Join(parts, ",")
|
|
}
|