use serde::{
Deserialize,
Deserializer,
Serializer,
de::{self, Visitor},
};
pub fn deserialize_f64<'de, D>(deserializer: D) -> Result<f64, D::Error>
where
D: Deserializer<'de>,
{
struct F64Visitor;
impl<'de> Visitor<'de> for F64Visitor {
type Value = f64;
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
formatter.write_str("a number or a string containing a number")
}
fn visit_f64<E>(self, value: f64) -> Result<Self::Value, E>
where
E: de::Error,
{
Ok(value)
}
fn visit_i64<E>(self, value: i64) -> Result<Self::Value, E>
where
E: de::Error,
{
Ok(value as f64)
}
fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
where
E: de::Error,
{
Ok(value as f64)
}
fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
where
E: de::Error,
{
value.parse::<f64>().map_err(E::custom)
}
}
deserializer.deserialize_any(F64Visitor)
}
pub fn deserialize_option_f64<'de, D>(deserializer: D) -> Result<Option<f64>, D::Error>
where
D: Deserializer<'de>,
{
let s: Option<String> = Option::deserialize(deserializer)?;
match s {
Some(s) => {
if s.is_empty() {
Ok(None)
} else {
s.parse::<f64>().map(Some).map_err(serde::de::Error::custom)
}
}
None => Ok(None),
}
}
pub fn deserialize_string_to_u64<'de, D>(deserializer: D) -> Result<u64, D::Error>
where
D: Deserializer<'de>,
{
let s = String::deserialize(deserializer)?;
s.parse::<u64>().map_err(serde::de::Error::custom)
}
pub fn deserialize_string_to_option_u64<'de, D>(deserializer: D) -> Result<Option<u64>, D::Error>
where
D: Deserializer<'de>,
{
let s: Option<String> = Option::deserialize(deserializer)?;
match s {
Some(s) => {
if s.is_empty() {
Ok(None)
} else {
s.parse::<u64>().map(Some).map_err(serde::de::Error::custom)
}
}
None => Ok(None),
}
}
pub fn serialize_as_string<T, S>(value: &T, serializer: S) -> Result<S::Ok, S::Error>
where
T: ToString,
S: Serializer,
{
serializer.serialize_str(&value.to_string())
}
pub fn serialize_option_as_string<T, S>(option: &Option<T>, serializer: S) -> Result<S::Ok, S::Error>
where
T: ToString,
S: Serializer,
{
match option {
Some(value) => serializer.serialize_str(&value.to_string()),
None => serializer.serialize_none(),
}
}