diff --git a/src/config/config_file/toml.rs b/src/config/config_file/toml.rs index 4e80cdd7d0..7c97c0801a 100644 --- a/src/config/config_file/toml.rs +++ b/src/config/config_file/toml.rs @@ -65,20 +65,22 @@ impl<'a> TomlParser<'a> { } } -pub fn deserialize_arr<'de, D, T>(deserializer: D) -> std::result::Result, D::Error> +pub fn deserialize_arr<'de, D, C, T>(deserializer: D) -> std::result::Result where D: de::Deserializer<'de>, + C: FromIterator + Deserialize<'de>, T: FromStr + Deserialize<'de>, ::Err: std::fmt::Display, { - struct ArrVisitor(std::marker::PhantomData); + struct ArrVisitor(std::marker::PhantomData<(C, T)>); - impl<'de, T> de::Visitor<'de> for ArrVisitor + impl<'de, C, T> de::Visitor<'de> for ArrVisitor where + C: FromIterator + Deserialize<'de>, T: FromStr + Deserialize<'de>, ::Err: std::fmt::Display, { - type Value = Vec; + type Value = C; fn expecting(&self, formatter: &mut Formatter) -> std::fmt::Result { formatter.write_str("a string, a map, or a list of strings/maps") } @@ -88,16 +90,15 @@ where E: de::Error, { let v = v.parse().map_err(de::Error::custom)?; - Ok(vec![v]) + Ok(std::iter::once(v).collect()) } fn visit_map(self, map: M) -> std::result::Result where M: de::MapAccess<'de>, { - Ok(vec![Deserialize::deserialize( - de::value::MapAccessDeserializer::new(map), - )?]) + let item = T::deserialize(de::value::MapAccessDeserializer::new(map))?; + Ok(std::iter::once(item).collect()) } fn visit_seq(self, seq: S) -> std::result::Result @@ -111,15 +112,13 @@ where Value(T), } let mut seq = seq; - let mut values = Vec::with_capacity(seq.size_hint().unwrap_or(0)); - while let Some(element) = seq.next_element::>()? { - let value = match element { - StringOrValue::String(s) => s.parse().map_err(de::Error::custom)?, - StringOrValue::Value(v) => v, - }; - values.push(value); - } - Ok(values) + std::iter::from_fn(|| seq.next_element::>().transpose()) + .map(|element| match element { + Ok(StringOrValue::String(s)) => s.parse().map_err(de::Error::custom), + Ok(StringOrValue::Value(v)) => Ok(v), + Err(e) => Err(e), + }) + .collect() } }