@@ -23,11 +23,19 @@ defmodule OptionParser do
2323
2424 ## Switches
2525
26- Extra information about switches can be given as argument too. This is useful
27- in order to say a switch must behave as a boolean, list, etc. The following
28- types are supported:
26+ Extra information about switches can be given as argument too.
27+ This is useful in order to say a switch must behave as a boolean
28+ or if duplicated switches should be kept, overriden or accumulated.
2929
30- * `:boolean` - They never consume the next value unless it is true/false;
30+ The following types are supported:
31+
32+ * `:boolean` - Mark the given switch as boolean. Boolean switches
33+ never consumes the following value unless it is
34+ true or false;
35+
36+ The following extra options are supported:
37+
38+ * `:keep` - Keep duplicated items in the list instead of overriding;
3139
3240 Examples:
3341
@@ -80,16 +88,18 @@ defmodule OptionParser do
8088
8189 defp parse ( [ "-" <> option | t ] , aliases , switches , dict , args , all ) do
8290 { option , value } = normalize_option ( option , aliases )
91+ kind = switches [ option ]
8392
8493 if value == nil do
8594 { value , t } =
86- case switch_type ( switches , option ) do
87- :boolean -> boolean_from_tail ( t )
88- _ -> value_from_tail ( t )
95+ if is_switch_a? :boolean , kind do
96+ boolean_from_tail ( t )
97+ else
98+ value_from_tail ( t )
8999 end
90100 end
91101
92- dict = store_option dict , option , value
102+ dict = store_option dict , option , value , kind
93103 parse ( t , aliases , switches , dict , args , all )
94104 end
95105
@@ -112,16 +122,22 @@ defmodule OptionParser do
112122 defp value_from_tail ( [ h | t ] ) , do: { h , t }
113123 defp value_from_tail ( [ ] ) , do: { true , [ ] }
114124
115- defp store_option ( dict , option , value ) when value in [ "false " , "true " ] do
116- store_option ( dict , option , binary_to_atom ( value ) )
125+ defp store_option ( dict , option , value , switches ) when value in [ "true " , "false " ] do
126+ store_option dict , option , binary_to_atom ( value ) , switches
117127 end
118128
119- defp store_option ( dict , option , value ) do
120- [ { option , value } | dict ]
129+ defp store_option ( dict , option , value , kind ) do
130+ if is_switch_a? :keep , kind do
131+ [ { option , value } | dict ]
132+ else
133+ [ { option , value } | Keyword . delete ( dict , option ) ]
134+ end
121135 end
122136
123137 defp reverse_dict ( dict , switches ) do
124- switches = lc { k , :boolean } in list switches , not Keyword . has_key? ( dict , k ) , do: { k , false }
138+ switches = lc { k , v } in list switches ,
139+ is_switch_a? ( :boolean , v ) ,
140+ not Keyword . has_key? ( dict , k ) , do: { k , false }
125141 Enum . reverse switches ++ dict
126142 end
127143
@@ -150,7 +166,7 @@ defmodule OptionParser do
150166 defp is_no? ( "no-" <> _ ) , do: true
151167 defp is_no? ( _ ) , do: false
152168
153- defp switch_type ( switches , option ) do
154- switches [ option ] || :default
155- end
169+ defp is_switch_a? ( kind , list ) when is_list ( list ) , do: List . member? ( list , kind )
170+ defp is_switch_a? ( kind , kind ) , do: true
171+ defp is_switch_a? ( _ , _ ) , do: false
156172end
0 commit comments