from_attr/
map.rs

1use from_attr_core::Pair;
2
3use crate::{ConvertParsed, PathValue};
4
5/// Represents a map parsed from the [`meta`](syn::meta::ParseNestedMeta).
6#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Default, Clone)]
7pub struct Map<K, V>(pub Vec<(K, V)>);
8
9impl<K, V> ConvertParsed for Map<K, V>
10where
11    K: ConvertParsed,
12    V: ConvertParsed,
13{
14    type Type = from_attr_core::Map<K::Type, V::Type>;
15
16    fn convert(path_value: PathValue<Self::Type>) -> syn::Result<Self> {
17        let PathValue { path, value } = path_value;
18
19        let mut pairs = Vec::new();
20        let mut errors = Vec::new();
21
22        value.pairs.into_iter().for_each(|Pair { key, value, .. }| {
23            match (
24                K::convert(PathValue { path, value: key }),
25                #[allow(clippy::redundant_field_names)]
26                V::convert(PathValue { path, value: value }),
27            ) {
28                (Ok(k), Ok(v)) => pairs.push((k, v)),
29                (Err(e), _) | (_, Err(e)) => errors.push(e),
30            }
31        });
32
33        match errors.into_iter().reduce(|mut a, b| {
34            a.combine(b);
35            a
36        }) {
37            Some(e) => Err(e),
38            None => Ok(Map(pairs)),
39        }
40    }
41
42    fn default() -> Option<Self> {
43        Some(Map(Vec::new()))
44    }
45}