#![doc(hidden)]
use std::str::FromStr;
use std::fmt::Display;
use std::result::Result as StdResult; use serde::{self, Deserializer, Deserialize, Serialize, Serializer};
use num_traits::{PrimInt, Num as NTraitNum};
use std::ops::{Deref, DerefMut};
pub(crate) fn deserialize_number_from_string<'de, T, D>(deserializer: D) -> Result<T, D::Error>
where
D: Deserializer<'de>,
T: FromStr + serde::Deserialize<'de> + PrimInt,
<T as FromStr>::Err: Display,
<T as NTraitNum>::FromStrRadixErr: Display
{
#[derive(Deserialize)]
#[serde(untagged)]
enum StringOrInt<T> {
String(String),
Number(T),
}
match StringOrInt::<T>::deserialize(deserializer)? {
StringOrInt::String(s) => {
if s.starts_with("0x") { T::from_str_radix(s.trim_start_matches("0x"), 16)
.map_err(serde::de::Error::custom)
} else {
s.parse::<T>()
.map_err(serde::de::Error::custom)
}
},
StringOrInt::Number(i) => Ok(i),
}
}
pub(crate) fn serialize_smt_pointer<T, S>(
object: &T, serializer: S
) -> StdResult<S::Ok, S::Error>
where
S: Serializer,
T: Deref,
<T as Deref>::Target: ::serde::Serialize
{
object.serialize(serializer)
}
pub(crate) fn deserialize_default_smt_pointer<'de, T, D>(deserializer: D) -> StdResult<T, D::Error>
where
D: Deserializer<'de>,
T: ::serde::Deserialize<'de> + DerefMut + Default, <T as Deref>::Target: Sized + ::serde::Deserialize<'de>,
{
#[derive(Deserialize)]
#[serde(untagged)]
enum Detect<SmtPointer, Val> {
Ptr(SmtPointer),
ValidValue(Val),
}
let unserialized: Detect<T, <T as Deref>::Target> = Detect::deserialize(
deserializer
)?;
match unserialized {
Detect::Ptr(p) => Ok(p), Detect::ValidValue(val) => Ok({
let mut new_smt_point = T::default();
*new_smt_point = val;
new_smt_point
}),
}
}
pub(crate) fn one_default<T>() -> T
where T: PrimInt + FromStr,
<T as FromStr>::Err: ::std::fmt::Debug
{ "1".parse().unwrap() }
pub(crate) fn oxffffff_default<T>() -> T
where T: PrimInt + FromStr,
<T as FromStr>::Err: ::std::fmt::Debug,
<T as NTraitNum>::FromStrRadixErr: ::std::fmt::Debug
{ T::from_str_radix("ffffff", 16).unwrap() }