@@ -154,6 +154,48 @@ pub fn values(input: &RadonMap) -> RadonArray {
154
154
let v: Vec < RadonTypes > = input. value ( ) . values ( ) . cloned ( ) . collect ( ) ;
155
155
RadonArray :: from ( v)
156
156
}
157
+
158
+ pub fn pick ( input : & RadonMap , args : & [ Value ] ) -> Result < RadonMap , RadError > {
159
+ let not_found = |key_str : & str | RadError :: MapKeyNotFound {
160
+ key : String :: from ( key_str)
161
+ } ;
162
+
163
+ let wrong_args = || RadError :: WrongArguments {
164
+ input_type : RadonMap :: radon_type_name ( ) ,
165
+ operator : "Pick" . to_string ( ) ,
166
+ args : args. to_vec ( ) ,
167
+ } ;
168
+
169
+ let mut input_keys = vec ! [ ] ;
170
+ if args. len ( ) > 1 {
171
+ return Err ( wrong_args ( ) ) ;
172
+ } else {
173
+ let first_arg = args. get ( 0 ) . ok_or_else ( wrong_args) ?;
174
+ match first_arg {
175
+ Value :: Array ( keys) => {
176
+ for key in keys. iter ( ) {
177
+ let key_string = from_value :: < String > ( key. to_owned ( ) ) . map_err ( |_| wrong_args ( ) ) ?;
178
+ input_keys. push ( key_string) ;
179
+ }
180
+ }
181
+ Value :: Text ( key) => {
182
+ input_keys. push ( key. clone ( ) ) ;
183
+ }
184
+ _ => return Err ( wrong_args ( ) )
185
+ } ;
186
+ }
187
+
188
+ let mut output_map = BTreeMap :: < String , RadonTypes > :: default ( ) ;
189
+ for key in input_keys {
190
+ if let Some ( value) = input. value ( ) . get ( & key) {
191
+ output_map. insert ( key, value. clone ( ) ) ;
192
+ } else {
193
+ return Err ( not_found ( key. as_str ( ) ) )
194
+ }
195
+ }
196
+ Ok ( RadonMap :: from ( output_map) )
197
+ }
198
+
157
199
pub fn stringify ( input : & RadonMap ) -> Result < RadonString , RadError > {
158
200
let json_string = serde_json:: to_string ( & input. value ( ) )
159
201
. map_err ( |_| RadError :: Decode {
0 commit comments