Skip to content

Commit f492676

Browse files
committed
feat: implement RadonOpCodes::MapPick
1 parent aae16d2 commit f492676

File tree

3 files changed

+44
-0
lines changed

3 files changed

+44
-0
lines changed

rad/src/operators/map.rs

+42
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,48 @@ pub fn values(input: &RadonMap) -> RadonArray {
154154
let v: Vec<RadonTypes> = input.value().values().cloned().collect();
155155
RadonArray::from(v)
156156
}
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+
157199
pub fn stringify(input: &RadonMap) -> Result<RadonString, RadError> {
158200
let json_string = serde_json::to_string(&input.value())
159201
.map_err(|_| RadError::Decode {

rad/src/operators/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ pub enum RadonOpCodes {
9696
MapValues = 0x69,
9797
//MapEntries = 0x6A,
9898
MapAlter = 0x6B,
99+
MapPick = 0x6E,
99100
///////////////////////////////////////////////////////////////////////
100101
// String operator codes (start at 0x70)
101102
StringAsBoolean = 0x70,

rad/src/types/map.rs

+1
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,7 @@ impl Operable for RadonMap {
162162
(RadonOpCodes::MapKeys, None) => Ok(RadonTypes::from(map_operators::keys(self))),
163163
(RadonOpCodes::MapValues, None) => Ok(RadonTypes::from(map_operators::values(self))),
164164
(RadonOpCodes::MapAlter, Some(args)) => map_operators::alter(self, args, context).map(RadonTypes::from),
165+
(RadonOpCodes::MapPick, Some(args)) => map_operators::pick(self, args).map(RadonTypes::from),
165166
(RadonOpCodes::MapStringify, None) => map_operators::stringify(self).map(RadonTypes::from),
166167
(op_code, args) => Err(RadError::UnsupportedOperator {
167168
input_type: RADON_MAP_TYPE_NAME.to_string(),

0 commit comments

Comments
 (0)