tarantool_rs/utils/
deser.rs1use rmpv::Value;
2use serde::de::DeserializeOwned;
3
4use crate::{codec::consts::keys, errors::DecodingError};
5
6pub fn value_to_map(value: Value) -> Result<Vec<(Value, Value)>, DecodingError> {
7 match value {
8 Value::Map(x) => Ok(x),
9 rest => Err(DecodingError::type_mismatch("map", rest.to_string())),
10 }
11}
12
13pub(crate) fn find_and_take_single_key_in_map(key: u8, map: Vec<(Value, Value)>) -> Option<Value> {
14 for (k, v) in map {
15 if matches!(k, Value::Integer(x) if x.as_u64().map_or(false, |y| y == key as u64)) {
16 return Some(v);
17 }
18 }
19 None
20}
21
22pub fn extract_iproto_data(value: Value) -> Result<Value, DecodingError> {
24 let map = value_to_map(value).map_err(|err| err.in_other("OK response body"))?;
25 find_and_take_single_key_in_map(keys::DATA, map)
26 .ok_or_else(|| DecodingError::missing_key("DATA").in_other("OK response body"))
27}
28
29pub fn extract_and_deserialize_iproto_data<T: DeserializeOwned>(
31 value: Value,
32) -> Result<T, DecodingError> {
33 extract_iproto_data(value).and_then(|x| rmpv::ext::from_value(x).map_err(Into::into))
34}