use std::ops::Index;
use rbs::Value;
use serde::de::DeserializeOwned;
use crate::Error;
pub fn decode_ref<T>(values: &Value) -> Result<T, Error>
where
T: DeserializeOwned,
{
match values {
Value::Array(_) => {
let direct_result = rbs::from_value_ref::<T>(values);
if direct_result.is_ok() {
return direct_result;
}
try_decode_map(values)
}
_ => {
Err(Error::from("decode error: expected array value"))
}
}
}
pub fn decode<T>(bs: Value) -> Result<T, Error>
where
T: DeserializeOwned,
{
decode_ref(&bs)
}
pub fn try_decode_map<T>(datas: &Value) -> Result<T, Error>
where
T: DeserializeOwned,
{
if datas.is_empty() {
return Err(Error::from("decode empty array value"));
}
if datas.len() > 1 {
return Err(Error::from(format!(
"[rb] rows.rows_affected > 1,but decode one type ({})!",
std::any::type_name::<T>()
)));
}
let values = datas.index(0);
if let Value::Map(arr) = values {
if arr.len() == 1 {
if let Some((_key, value)) = arr.into_iter().next() {
if let Ok(result) = rbs::from_value_ref::<T>(value) {
return Ok(result);
}
}
}
}
let arr: Vec<T> = rbs::from_value_ref(datas)?;
arr.into_iter().next().ok_or_else(|| {
Error::from(format!(
"[rb] decode fail: cannot decode into type {} from empty result",
std::any::type_name::<T>()
))
})
}
pub fn is_debug_mode() -> bool {
cfg!(all(debug_assertions, feature = "debug_mode"))
}