1use crate::PrfVisitorError;
2
3pub enum ResolvedPrf<Block, Passthrough> {
8 Block(Block),
9 Sequence(Vec<ResolvedPrf<Block, Passthrough>>),
10 Map(Vec<(String, ResolvedPrf<Block, Passthrough>)>),
11 Absent,
12 Passthrough(Passthrough),
13}
14
15impl<Block, Passthrough> ResolvedPrf<Block, Passthrough> {
16 pub fn visit<V>(self, visitor: V) -> Result<V::Value, PrfVisitorError>
17 where
18 V: PrfVisitor<Block, Passthrough>,
19 {
20 match self {
21 Self::Block(block) => visitor.visit_block(block),
22 Self::Sequence(values) => visitor.visit_seq(SeqAccess::new(values)),
23 Self::Map(entries) => visitor.visit_map(MapAccess::new(entries)),
24 Self::Absent => visitor.visit_absent(),
25 Self::Passthrough(value) => visitor.visit_passthrough(value),
26 }
27 }
28}
29
30pub struct SeqAccess<Block, Passthrough> {
32 values: std::vec::IntoIter<ResolvedPrf<Block, Passthrough>>,
33}
34
35impl<Block, Passthrough> SeqAccess<Block, Passthrough> {
36 pub fn new(values: Vec<ResolvedPrf<Block, Passthrough>>) -> Self {
37 Self {
38 values: values.into_iter(),
39 }
40 }
41
42 pub fn next_node(&mut self) -> Option<ResolvedPrf<Block, Passthrough>> {
43 self.values.next()
44 }
45
46 pub fn len(&self) -> usize {
47 self.values.len()
48 }
49
50 pub fn is_empty(&self) -> bool {
51 self.values.len() == 0
52 }
53}
54
55impl<Block, Passthrough> Iterator for SeqAccess<Block, Passthrough> {
56 type Item = ResolvedPrf<Block, Passthrough>;
57
58 fn next(&mut self) -> Option<Self::Item> {
59 self.next_node()
60 }
61
62 fn size_hint(&self) -> (usize, Option<usize>) {
63 self.values.size_hint()
64 }
65}
66
67impl<Block, Passthrough> ExactSizeIterator for SeqAccess<Block, Passthrough> {}
68
69pub struct MapAccess<Block, Passthrough> {
71 entries: std::vec::IntoIter<(String, ResolvedPrf<Block, Passthrough>)>,
72}
73
74impl<Block, Passthrough> MapAccess<Block, Passthrough> {
75 pub fn new(entries: Vec<(String, ResolvedPrf<Block, Passthrough>)>) -> Self {
76 Self {
77 entries: entries.into_iter(),
78 }
79 }
80
81 pub fn next_entry(&mut self) -> Option<(String, ResolvedPrf<Block, Passthrough>)> {
82 self.entries.next()
83 }
84
85 pub fn len(&self) -> usize {
86 self.entries.len()
87 }
88
89 pub fn is_empty(&self) -> bool {
90 self.entries.len() == 0
91 }
92}
93
94impl<Block, Passthrough> Iterator for MapAccess<Block, Passthrough> {
95 type Item = (String, ResolvedPrf<Block, Passthrough>);
96
97 fn next(&mut self) -> Option<Self::Item> {
98 self.next_entry()
99 }
100
101 fn size_hint(&self) -> (usize, Option<usize>) {
102 self.entries.size_hint()
103 }
104}
105
106impl<Block, Passthrough> ExactSizeIterator for MapAccess<Block, Passthrough> {}
107
108#[cfg(test)]
109mod access_tests {
110 use super::{MapAccess, ResolvedPrf, SeqAccess};
111
112 #[test]
113 fn sequence_access_reports_its_exact_remaining_length() {
114 let mut seq = SeqAccess::<u8, ()>::new(vec![ResolvedPrf::Block(1), ResolvedPrf::Block(2)]);
115
116 assert_eq!(seq.len(), 2);
117 assert_eq!(seq.size_hint(), (2, Some(2)));
118 assert!(!seq.is_empty());
119 assert!(seq.next().is_some());
120 assert_eq!(seq.len(), 1);
121 assert!(seq.next().is_some());
122 assert_eq!(seq.size_hint(), (0, Some(0)));
123 assert!(seq.is_empty());
124 }
125
126 #[test]
127 fn map_access_reports_its_exact_remaining_length() {
128 let mut map = MapAccess::<u8, ()>::new(vec![
129 (String::from("one"), ResolvedPrf::Block(1)),
130 (String::from("two"), ResolvedPrf::Block(2)),
131 ]);
132
133 assert_eq!(map.len(), 2);
134 assert_eq!(map.size_hint(), (2, Some(2)));
135 assert!(!map.is_empty());
136 assert!(map.next().is_some());
137 assert_eq!(map.len(), 1);
138 assert!(map.next().is_some());
139 assert_eq!(map.size_hint(), (0, Some(0)));
140 assert!(map.is_empty());
141 }
142}
143
144pub trait PrfVisitor<Block, Passthrough>: Sized + 'static {
146 type Value: Send + 'static;
147
148 fn visit_block(self, _block: Block) -> Result<Self::Value, PrfVisitorError> {
149 Err(PrfVisitorError::UnexpectedShape)
150 }
151
152 fn visit_seq(
153 self,
154 _seq: SeqAccess<Block, Passthrough>,
155 ) -> Result<Self::Value, PrfVisitorError> {
156 Err(PrfVisitorError::UnexpectedShape)
157 }
158
159 fn visit_map(
160 self,
161 _map: MapAccess<Block, Passthrough>,
162 ) -> Result<Self::Value, PrfVisitorError> {
163 Err(PrfVisitorError::UnexpectedShape)
164 }
165
166 fn visit_absent(self) -> Result<Self::Value, PrfVisitorError> {
167 Err(PrfVisitorError::UnexpectedShape)
168 }
169
170 fn visit_passthrough(self, _value: Passthrough) -> Result<Self::Value, PrfVisitorError> {
173 Err(PrfVisitorError::UnexpectedShape)
174 }
175}
176
177#[derive(Debug, Clone, Copy, Default)]
179pub struct BlockVisitor;
180
181impl<Block, Passthrough> PrfVisitor<Block, Passthrough> for BlockVisitor
182where
183 Block: Send + 'static,
184{
185 type Value = Block;
186
187 fn visit_block(self, block: Block) -> Result<Self::Value, PrfVisitorError> {
188 Ok(block)
189 }
190}
191
192impl<Block, Passthrough> PrfVisitor<Block, Passthrough> for ResolvedVisitor
198where
199 Block: Send + 'static,
200 Passthrough: Send + 'static,
201{
202 type Value = ResolvedPrf<Block, Passthrough>;
203
204 fn visit_block(self, block: Block) -> Result<Self::Value, PrfVisitorError> {
205 Ok(ResolvedPrf::Block(block))
206 }
207
208 fn visit_seq(self, seq: SeqAccess<Block, Passthrough>) -> Result<Self::Value, PrfVisitorError> {
209 Ok(ResolvedPrf::Sequence(seq.collect()))
210 }
211
212 fn visit_map(self, map: MapAccess<Block, Passthrough>) -> Result<Self::Value, PrfVisitorError> {
213 Ok(ResolvedPrf::Map(map.collect()))
214 }
215
216 fn visit_absent(self) -> Result<Self::Value, PrfVisitorError> {
217 Ok(ResolvedPrf::Absent)
218 }
219
220 fn visit_passthrough(self, value: Passthrough) -> Result<Self::Value, PrfVisitorError> {
221 Ok(ResolvedPrf::Passthrough(value))
222 }
223}
224
225#[derive(Clone, Copy)]
226pub struct ResolvedVisitor;