use std::ops::Index;
use rbs::{Value};
use serde::de::DeserializeOwned;
use crate::Error;
pub fn decode_ref<T: ?Sized>(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 an not array value"))
}
}
}
pub fn decode<T: ?Sized>(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.len() > 2 {
return Err(Error::from(format!(
"[rb] rows.rows_affected > 1,but decode one type ({})!",
std::any::type_name::<T>()
)));
}
if datas.len() <= 1 {
return Ok(rbs::from_value::<T>(Value::Null)?);
}
let values = datas.index(1);
match values {
Value::Array(arr) => {
if arr.len() == 1 {
if let Some(value) = arr.first() {
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("fail type"))
}
pub fn is_debug_mode() -> bool {
if cfg!(debug_assertions) {
#[cfg(feature = "debug_mode")]
{
true
}
#[cfg(not(feature = "debug_mode"))]
{
false
}
} else {
false
}
}