string_to_string.go (5360B)
1 package pflag 2 3 import ( 4 "bytes" 5 "encoding/csv" 6 "fmt" 7 "strings" 8 ) 9 10 // -- stringToString Value 11 type stringToStringValue struct { 12 value *map[string]string 13 changed bool 14 } 15 16 func newStringToStringValue(val map[string]string, p *map[string]string) *stringToStringValue { 17 ssv := new(stringToStringValue) 18 ssv.value = p 19 *ssv.value = val 20 return ssv 21 } 22 23 // Format: a=1,b=2 24 func (s *stringToStringValue) Set(val string) error { 25 var ss []string 26 n := strings.Count(val, "=") 27 switch n { 28 case 0: 29 return fmt.Errorf("%s must be formatted as key=value", val) 30 case 1: 31 ss = append(ss, strings.Trim(val, `"`)) 32 default: 33 r := csv.NewReader(strings.NewReader(val)) 34 var err error 35 ss, err = r.Read() 36 if err != nil { 37 return err 38 } 39 } 40 41 out := make(map[string]string, len(ss)) 42 for _, pair := range ss { 43 kv := strings.SplitN(pair, "=", 2) 44 if len(kv) != 2 { 45 return fmt.Errorf("%s must be formatted as key=value", pair) 46 } 47 out[kv[0]] = kv[1] 48 } 49 if !s.changed { 50 *s.value = out 51 } else { 52 for k, v := range out { 53 (*s.value)[k] = v 54 } 55 } 56 s.changed = true 57 return nil 58 } 59 60 func (s *stringToStringValue) Type() string { 61 return "stringToString" 62 } 63 64 func (s *stringToStringValue) String() string { 65 records := make([]string, 0, len(*s.value)>>1) 66 for k, v := range *s.value { 67 records = append(records, k+"="+v) 68 } 69 70 var buf bytes.Buffer 71 w := csv.NewWriter(&buf) 72 if err := w.Write(records); err != nil { 73 panic(err) 74 } 75 w.Flush() 76 return "[" + strings.TrimSpace(buf.String()) + "]" 77 } 78 79 func stringToStringConv(val string) (interface{}, error) { 80 val = strings.Trim(val, "[]") 81 // An empty string would cause an empty map 82 if len(val) == 0 { 83 return map[string]string{}, nil 84 } 85 r := csv.NewReader(strings.NewReader(val)) 86 ss, err := r.Read() 87 if err != nil { 88 return nil, err 89 } 90 out := make(map[string]string, len(ss)) 91 for _, pair := range ss { 92 kv := strings.SplitN(pair, "=", 2) 93 if len(kv) != 2 { 94 return nil, fmt.Errorf("%s must be formatted as key=value", pair) 95 } 96 out[kv[0]] = kv[1] 97 } 98 return out, nil 99 } 100 101 // GetStringToString return the map[string]string value of a flag with the given name 102 func (f *FlagSet) GetStringToString(name string) (map[string]string, error) { 103 val, err := f.getFlagType(name, "stringToString", stringToStringConv) 104 if err != nil { 105 return map[string]string{}, err 106 } 107 return val.(map[string]string), nil 108 } 109 110 // StringToStringVar defines a string flag with specified name, default value, and usage string. 111 // The argument p points to a map[string]string variable in which to store the values of the multiple flags. 112 // The value of each argument will not try to be separated by comma 113 func (f *FlagSet) StringToStringVar(p *map[string]string, name string, value map[string]string, usage string) { 114 f.VarP(newStringToStringValue(value, p), name, "", usage) 115 } 116 117 // StringToStringVarP is like StringToStringVar, but accepts a shorthand letter that can be used after a single dash. 118 func (f *FlagSet) StringToStringVarP(p *map[string]string, name, shorthand string, value map[string]string, usage string) { 119 f.VarP(newStringToStringValue(value, p), name, shorthand, usage) 120 } 121 122 // StringToStringVar defines a string flag with specified name, default value, and usage string. 123 // The argument p points to a map[string]string variable in which to store the value of the flag. 124 // The value of each argument will not try to be separated by comma 125 func StringToStringVar(p *map[string]string, name string, value map[string]string, usage string) { 126 CommandLine.VarP(newStringToStringValue(value, p), name, "", usage) 127 } 128 129 // StringToStringVarP is like StringToStringVar, but accepts a shorthand letter that can be used after a single dash. 130 func StringToStringVarP(p *map[string]string, name, shorthand string, value map[string]string, usage string) { 131 CommandLine.VarP(newStringToStringValue(value, p), name, shorthand, usage) 132 } 133 134 // StringToString defines a string flag with specified name, default value, and usage string. 135 // The return value is the address of a map[string]string variable that stores the value of the flag. 136 // The value of each argument will not try to be separated by comma 137 func (f *FlagSet) StringToString(name string, value map[string]string, usage string) *map[string]string { 138 p := map[string]string{} 139 f.StringToStringVarP(&p, name, "", value, usage) 140 return &p 141 } 142 143 // StringToStringP is like StringToString, but accepts a shorthand letter that can be used after a single dash. 144 func (f *FlagSet) StringToStringP(name, shorthand string, value map[string]string, usage string) *map[string]string { 145 p := map[string]string{} 146 f.StringToStringVarP(&p, name, shorthand, value, usage) 147 return &p 148 } 149 150 // StringToString defines a string flag with specified name, default value, and usage string. 151 // The return value is the address of a map[string]string variable that stores the value of the flag. 152 // The value of each argument will not try to be separated by comma 153 func StringToString(name string, value map[string]string, usage string) *map[string]string { 154 return CommandLine.StringToStringP(name, "", value, usage) 155 } 156 157 // StringToStringP is like StringToString, but accepts a shorthand letter that can be used after a single dash. 158 func StringToStringP(name, shorthand string, value map[string]string, usage string) *map[string]string { 159 return CommandLine.StringToStringP(name, shorthand, value, usage) 160 }