use crate::Str;
use num_decimal::Num;
use serde::Deserialize;
use serde::Deserializer;
use serde::Serialize;
use serde::Serializer;
use serde_variant::to_variant_name;
pub(crate) fn abs_num_from_str<'de, D>(deserializer: D) -> Result<Num, D::Error>
where
D: Deserializer<'de>,
{
Num::deserialize(deserializer).map(|num| if num.is_negative() { num * -1 } else { num })
}
pub(crate) fn vec_from_str<'de, D, T>(deserializer: D) -> Result<Vec<T>, D::Error>
where
D: Deserializer<'de>,
T: Deserialize<'de>,
{
let vec = Option::<Vec<T>>::deserialize(deserializer)?;
Ok(vec.unwrap_or_default())
}
pub(crate) fn vec_from_comma_separated_str<'de, D>(deserializer: D) -> Result<Vec<String>, D::Error>
where
D: Deserializer<'de>,
{
let vec = Option::<String>::deserialize(deserializer)?
.map(|string| string.split(',').map(str::to_owned).collect())
.unwrap_or_default();
Ok(vec)
}
pub(crate) fn slice_to_str<S, F, T>(
slice: &[T],
name_fn: F,
serializer: S,
) -> Result<S::Ok, S::Error>
where
S: Serializer,
F: Fn(&T) -> Str,
T: Serialize,
{
if !slice.is_empty() {
let s = slice.iter().map(name_fn).collect::<Vec<_>>().join(",");
serializer.serialize_str(&s)
} else {
serializer.serialize_none()
}
}
pub(crate) fn enum_slice_to_str<S, T>(slice: &[T], serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
T: Serialize,
{
fn name_fn<T>(variant: &T) -> Str
where
T: Serialize,
{
to_variant_name(variant).unwrap().into()
}
slice_to_str(slice, name_fn, serializer)
}
pub(crate) fn string_slice_to_str<S>(slice: &[String], serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
#[allow(clippy::ptr_arg)]
fn name_fn(string: &String) -> Str {
string.clone().into()
}
slice_to_str(slice, name_fn, serializer)
}