ast_description_lang/collections/
impls.rs1use 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}