@@ -23,11 +23,19 @@ defmodule OptionParser do
23
23
24
24
## Switches
25
25
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.
29
29
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;
31
39
32
40
Examples:
33
41
@@ -80,16 +88,18 @@ defmodule OptionParser do
80
88
81
89
defp parse ( [ "-" <> option | t ] , aliases , switches , dict , args , all ) do
82
90
{ option , value } = normalize_option ( option , aliases )
91
+ kind = switches [ option ]
83
92
84
93
if value == nil do
85
94
{ 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 )
89
99
end
90
100
end
91
101
92
- dict = store_option dict , option , value
102
+ dict = store_option dict , option , value , kind
93
103
parse ( t , aliases , switches , dict , args , all )
94
104
end
95
105
@@ -112,16 +122,22 @@ defmodule OptionParser do
112
122
defp value_from_tail ( [ h | t ] ) , do: { h , t }
113
123
defp value_from_tail ( [ ] ) , do: { true , [ ] }
114
124
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
117
127
end
118
128
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
121
135
end
122
136
123
137
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 }
125
141
Enum . reverse switches ++ dict
126
142
end
127
143
@@ -150,7 +166,7 @@ defmodule OptionParser do
150
166
defp is_no? ( "no-" <> _ ) , do: true
151
167
defp is_no? ( _ ) , do: false
152
168
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
156
172
end
0 commit comments