42 lines
1.2 KiB
Rust
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))
|
|
}
|