ast_description_lang/collections/
impls.rs

1use super::{NamedItem, NamedSet, Unnamed, Wrapper};
2use serde::{
3  de::{self, Error, MapAccess},
4  Deserialize, Deserializer,
5};
6use std::{
7  any,
8  cmp::Ordering,
9  fmt::{self, Formatter},
10  hash::{Hash, Hasher},
11  marker::PhantomData,
12  ops::Index,
13};
14
15impl<'ni, T: NamedItem<'ni>> FromIterator<T> for NamedSet<'ni, T> {
16  fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
17    NamedSet(
18      iter
19        .into_iter()
20        .map(|item| Wrapper(item, PhantomData))
21        .collect(),
22    )
23  }
24}
25
26impl<'ni, T: NamedItem<'ni>> FromIterator<(T::Name, T::Unnamed)> for NamedSet<'ni, T> {
27  fn from_iter<I: IntoIterator<Item = (T::Name, T::Unnamed)>>(iter: I) -> Self {
28    NamedSet::from_iter(
29      iter
30        .into_iter()
31        .map(|(name, unnamed)| unnamed.add_name(name)),
32    )
33  }
34}
35
36impl<'ni, T: NamedItem<'ni>> Default for NamedSet<'ni, T> {
37  fn default() -> Self {
38    NamedSet(Default::default())
39  }
40}
41
42impl<'ni, T: NamedItem<'ni>> Index<usize> for NamedSet<'ni, T> {
43  type Output = T;
44
45  fn index(&self, index: usize) -> &Self::Output {
46    &self.0[index].0
47  }
48}
49
50impl<'de, 'ni, T> Deserialize<'de> for NamedSet<'ni, T>
51where
52  'de: 'ni,
53  T: NamedItem<'ni>,
54  <T as NamedItem<'ni>>::Name: Deserialize<'de>,
55  <T as NamedItem<'ni>>::Unnamed: Deserialize<'de>,
56{
57  fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
58    return deserializer.deserialize_map(Visitor(PhantomData, PhantomData));
59
60    struct Visitor<'de, 'ni, T>(PhantomData<&'ni &'de ()>, PhantomData<T>)
61    where
62      'de: 'ni,
63      T: NamedItem<'ni>,
64      <T as NamedItem<'ni>>::Name: Deserialize<'de>,
65      <T as NamedItem<'ni>>::Unnamed: Deserialize<'de>;
66
67    impl<'de, 'ni, T> de::Visitor<'de> for Visitor<'de, 'ni, T>
68    where
69      'de: 'ni,
70      T: NamedItem<'ni>,
71      <T as NamedItem<'ni>>::Name: Deserialize<'de>,
72      <T as NamedItem<'ni>>::Unnamed: Deserialize<'de>,
73    {
74      type Value = NamedSet<'ni, T>;
75
76      fn expecting(&self, f: &mut Formatter) -> fmt::Result {
77        write!(f, "a collection of type `{}`", any::type_name::<T>())
78      }
79
80      fn visit_map<A: MapAccess<'de>>(self, mut map: A) -> Result<Self::Value, A::Error> {
81        let mut named_set = Self::Value::default();
82
83        while let Some((name, unnamed)) = map.next_entry()? {
84          let unnamed: T::Unnamed = unnamed;
85          if !named_set.insert(unnamed.add_name(name)) {
86            return Err(A::Error::custom(format!(
87              "duplicate entry `{name}` in collection of type `{}`",
88              any::type_name::<T>()
89            )));
90          }
91        }
92
93        Ok(named_set)
94      }
95    }
96  }
97}
98
99impl<'ni, T: NamedItem<'ni>> Hash for Wrapper<'ni, T> {
100  fn hash<H: Hasher>(&self, state: &mut H) {
101    self.0.name().hash(state)
102  }
103}
104
105impl<'ni, T: NamedItem<'ni>> Ord for Wrapper<'ni, T> {
106  fn cmp(&self, other: &Self) -> Ordering {
107    self.0.name().cmp(&other.0.name())
108  }
109}
110
111impl<'ni, T: NamedItem<'ni>> PartialOrd for Wrapper<'ni, T> {
112  fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
113    Some(self.cmp(other))
114  }
115}
116
117impl<'ni, T: NamedItem<'ni>> Eq for Wrapper<'ni, T> {}
118
119impl<'ni, T: NamedItem<'ni>> PartialEq for Wrapper<'ni, T> {
120  fn eq(&self, other: &Self) -> bool {
121    self.cmp(other) == Ordering::Equal
122  }
123}