flabk/src/astreams/serde_ext.rs

42 lines
1.2 KiB
Rust

use std::{fmt, marker::PhantomData};
use serde::{de, Deserialize, Deserializer};
// Allows deserialization of a single item into a vector of that item
// As long as they implement the From<String> trait
pub(super) fn pull_single_into_vec<'de, D, T>(deserializer: D) -> Result<Vec<T>, D::Error>
where
D: Deserializer<'de>,
T: From<String> + serde::Deserialize<'de>,
{
struct VecComposer<T>(PhantomData<Vec<T>>);
impl<'de, T> de::Visitor<'de> for VecComposer<T>
where
T: From<String> + serde::Deserialize<'de>,
{
type Value = Vec<T>;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
let name = std::any::type_name::<T>();
formatter.write_str(format!("expected {} or Vec<{}>", name, name).as_str())
}
fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
where
E: de::Error,
{
Ok(vec![value.to_string().into()])
}
fn visit_seq<S>(self, visitor: S) -> Result<Self::Value, S::Error>
where
S: de::SeqAccess<'de>,
{
Deserialize::deserialize(de::value::SeqAccessDeserializer::new(visitor))
}
}
deserializer.deserialize_any(VecComposer(PhantomData))
}