@@ -21,7 +21,7 @@ func newStringToStringValue(val map[string]string, p *map[string]string) *string
2121 return ssv
2222}
2323
24- // Format: a=1,b=2
24+ // Set updates the flag value from the given string, adding additional mappings or updating existing ones.
2525func (s * stringToStringValue ) Set (val string ) error {
2626 var ss []string
2727 n := strings .Count (val , "=" )
@@ -47,13 +47,17 @@ func (s *stringToStringValue) Set(val string) error {
4747 }
4848 out [kv [0 ]] = kv [1 ]
4949 }
50+
51+ // clear out any default flag values
5052 if ! s .changed {
51- * s .value = out
52- } else {
53- for k , v := range out {
54- (* s .value )[k ] = v
53+ for k := range * s .value {
54+ delete (* s .value , k )
5555 }
5656 }
57+
58+ for k , v := range out {
59+ (* s .value )[k ] = v
60+ }
5761 s .changed = true
5862 return nil
5963}
@@ -84,85 +88,100 @@ func (s *stringToStringValue) String() string {
8488 return "[" + strings .TrimSpace (buf .String ()) + "]"
8589}
8690
87- func stringToStringConv (val string ) (interface {}, error ) {
88- val = strings .Trim (val , "[]" )
89- // An empty string would cause an empty map
90- if len (val ) == 0 {
91- return map [string ]string {}, nil
92- }
93- r := csv .NewReader (strings .NewReader (val ))
94- ss , err := r .Read ()
95- if err != nil {
96- return nil , err
97- }
98- out := make (map [string ]string , len (ss ))
99- for _ , pair := range ss {
100- kv := strings .SplitN (pair , "=" , 2 )
101- if len (kv ) != 2 {
102- return nil , fmt .Errorf ("%s must be formatted as key=value" , pair )
103- }
104- out [kv [0 ]] = kv [1 ]
105- }
106- return out , nil
107- }
108-
109- // GetStringToString return the map[string]string value of a flag with the given name
91+ // GetStringToString return the map value of a flag with the given name from f. The returned map shares memory with the
92+ // internal flag value [Flag.Value].
11093func (f * FlagSet ) GetStringToString (name string ) (map [string ]string , error ) {
111- val , err := f .getFlagType (name , "stringToString" , stringToStringConv )
94+ val , err := f .getFlagType (name , "stringToString" , nil )
11295 if err != nil {
11396 return map [string ]string {}, err
11497 }
115- return val .(map [string ]string ), nil
116- }
117-
118- // StringToStringVar defines a string flag with specified name, default value, and usage string.
119- // The argument p points to a map[string]string variable in which to store the values of the multiple flags.
120- // The value of each argument will not try to be separated by comma
121- func (f * FlagSet ) StringToStringVar (p * map [string ]string , name string , value map [string ]string , usage string ) {
122- f .VarP (newStringToStringValue (value , p ), name , "" , usage )
123- }
124-
125- // StringToStringVarP is like StringToStringVar, but accepts a shorthand letter that can be used after a single dash.
126- func (f * FlagSet ) StringToStringVarP (p * map [string ]string , name , shorthand string , value map [string ]string , usage string ) {
127- f .VarP (newStringToStringValue (value , p ), name , shorthand , usage )
128- }
12998
130- // StringToStringVar defines a string flag with specified name, default value, and usage string.
131- // The argument p points to a map[string]string variable in which to store the value of the flag.
132- // The value of each argument will not try to be separated by comma
133- func StringToStringVar (p * map [string ]string , name string , value map [string ]string , usage string ) {
134- CommandLine .VarP (newStringToStringValue (value , p ), name , "" , usage )
135- }
99+ fv , ok := val .(* stringToStringValue )
100+ if ! ok {
101+ panic (fmt .Errorf ("illegal state: unspected internal type for stringToString flag '%s'" , name ))
102+ }
103+ if fv .value == nil {
104+ return nil , nil
105+ }
136106
137- // StringToStringVarP is like StringToStringVar, but accepts a shorthand letter that can be used after a single dash.
138- func StringToStringVarP (p * map [string ]string , name , shorthand string , value map [string ]string , usage string ) {
139- CommandLine .VarP (newStringToStringValue (value , p ), name , shorthand , usage )
107+ return * fv .value , nil
140108}
141109
142- // StringToString defines a string flag with specified name, default value, and usage string.
143- // The return value is the address of a map[string]string variable that stores the value of the flag.
144- // The value of each argument will not try to be separated by comma
110+ // StringToString defines a map flag with specified name, default value, and usage string.
111+ //
112+ // StringToString flags are used to pass key=value pairs to applications. The same flag can be provided more than once
113+ // with all key=value pairs being merged into a final map. Multiple key=value pairs may be provided in a single arg,
114+ // separated by commas. A few simple examples include:
115+ //
116+ // --arg a=1 -> map[string]string{ "a": "1" }
117+ // --arg a=1 --arg b=2 -> map[string]string{ "a": "1", "b": "2" }
118+ // --arg a=1,b=2 -> map[string]string{ "a": "1", "b": "2" }
119+ // --arg=a=1 -> map[string]string{ "a": "1" }
120+ //
121+ // As a special case, a single key=value pair whose value contains a comma will be interpreted as shown below:
122+ //
123+ // --arg a=1,2 -> map[string]string{ "a": "1,2" }
124+ //
125+ // Returns a pointer to the map which will be updated upon invocation of [FlagSet.Parse], [Flag.Value.Set], and others.
145126func (f * FlagSet ) StringToString (name string , value map [string ]string , usage string ) * map [string ]string {
146127 p := map [string ]string {}
147128 f .StringToStringVarP (& p , name , "" , value , usage )
148129 return & p
149130}
150131
151- // StringToStringP is like StringToString, but accepts a shorthand letter that can be used after a single dash.
132+ // StringToStringP is like [FlagSet.StringToString], but also accepts a shorthand letter that can be used after a single
133+ // dash.
134+ //
135+ // See [FlagSet.StringToString].
152136func (f * FlagSet ) StringToStringP (name , shorthand string , value map [string ]string , usage string ) * map [string ]string {
153137 p := map [string ]string {}
154138 f .StringToStringVarP (& p , name , shorthand , value , usage )
155139 return & p
156140}
157141
142+ // StringToStringVar is like [FlagSet.StringToString], but also accepts a map pointer argument p which is updated with
143+ // the parsed key-value pairs.
144+ //
145+ // See [FlagSet.StringToString].
146+ func (f * FlagSet ) StringToStringVar (p * map [string ]string , name string , value map [string ]string , usage string ) {
147+ f .VarP (newStringToStringValue (value , p ), name , "" , usage )
148+ }
149+
150+ // StringToStringVarP is like [FlagSet.StringToString], but also accepts a map pointer argument p which is updated with
151+ // the parsed key-value pairs, and a shorthand letter that can be used after a single dash.
152+ //
153+ // See [FlagSet.StringToString].
154+ func (f * FlagSet ) StringToStringVarP (p * map [string ]string , name , shorthand string , value map [string ]string , usage string ) {
155+ f .VarP (newStringToStringValue (value , p ), name , shorthand , usage )
156+ }
157+
158158// StringToString defines a string flag with specified name, default value, and usage string.
159- // The return value is the address of a map[string]string variable that stores the value of the flag.
160- // The value of each argument will not try to be separated by comma
159+ //
160+ // See [FlagSet.StringToString].
161161func StringToString (name string , value map [string ]string , usage string ) * map [string ]string {
162162 return CommandLine .StringToStringP (name , "" , value , usage )
163163}
164164
165- // StringToStringP is like StringToString, but accepts a shorthand letter that can be used after a single dash.
165+ // StringToStringP is like [FlagSet.StringToString], but also accepts a shorthand letter that can be used after a single
166+ // dash.
167+ //
168+ // See [FlagSet.StringToString].
166169func StringToStringP (name , shorthand string , value map [string ]string , usage string ) * map [string ]string {
167170 return CommandLine .StringToStringP (name , shorthand , value , usage )
168171}
172+
173+ // StringToStringVar is like [FlagSet.StringToString], but also accepts a map pointer argument p which is updated with
174+ // the parsed key-value pairs.
175+ //
176+ // See [FlagSet.StringToString].
177+ func StringToStringVar (p * map [string ]string , name string , value map [string ]string , usage string ) {
178+ CommandLine .VarP (newStringToStringValue (value , p ), name , "" , usage )
179+ }
180+
181+ // StringToStringVarP is like [FlagSet.StringToString], but also accepts a map pointer argument p which is updated with
182+ // the parsed key-value pairs, and a shorthand letter that can be used after a single dash.
183+ //
184+ // See [FlagSet.StringToString].
185+ func StringToStringVarP (p * map [string ]string , name , shorthand string , value map [string ]string , usage string ) {
186+ CommandLine .VarP (newStringToStringValue (value , p ), name , shorthand , usage )
187+ }
0 commit comments