reed_solomon_simd/
encoder_result.rs1use crate::rate::EncoderWork;
2
3pub struct EncoderResult<'a> {
14 work: &'a mut EncoderWork,
15}
16
17impl EncoderResult<'_> {
18 pub fn recovery(&self, index: usize) -> Option<&[u8]> {
24 self.work.recovery(index)
25 }
26
27 pub fn recovery_iter(&self) -> Recovery<'_> {
32 Recovery::new(self.work)
33 }
34}
35
36impl<'a> EncoderResult<'a> {
40 pub(crate) fn new(work: &'a mut EncoderWork) -> Self {
41 Self { work }
42 }
43}
44
45impl Drop for EncoderResult<'_> {
49 fn drop(&mut self) {
50 self.work.reset_received();
51 }
52}
53
54pub struct Recovery<'a> {
61 ended: bool,
62 next_index: usize,
63 work: &'a EncoderWork,
64}
65
66impl<'a> Iterator for Recovery<'a> {
70 type Item = &'a [u8];
71 fn next(&mut self) -> Option<&'a [u8]> {
72 if self.ended {
73 None
74 } else if let Some(next) = self.work.recovery(self.next_index) {
75 self.next_index += 1;
76 Some(next)
77 } else {
78 self.ended = true;
79 None
80 }
81 }
82
83 fn size_hint(&self) -> (usize, Option<usize>) {
84 let remaining = self.work.recovery_count() - self.next_index;
85 (remaining, Some(remaining))
86 }
87}
88
89impl ExactSizeIterator for Recovery<'_> {}
93
94impl<'a> Recovery<'a> {
98 pub(crate) fn new(work: &'a EncoderWork) -> Self {
99 Self {
100 ended: false,
101 next_index: 0,
102 work,
103 }
104 }
105}
106
107#[cfg(test)]
111mod tests {
112 use super::*;
113 use crate::{test_util, ReedSolomonEncoder};
114
115 #[cfg(not(feature = "std"))]
116 use alloc::vec::Vec;
117
118 #[test]
119 fn encoder_result() {
123 let original = test_util::generate_original(2, 1024, 123);
124 let mut encoder = ReedSolomonEncoder::new(2, 3, 1024).unwrap();
125
126 for original in &original {
127 encoder.add_original_shard(original).unwrap();
128 }
129
130 let result: EncoderResult = encoder.encode().unwrap();
131
132 let mut all = Vec::new();
133 all.push(result.recovery(0).unwrap());
134 all.push(result.recovery(1).unwrap());
135 all.push(result.recovery(2).unwrap());
136 assert!(result.recovery(3).is_none());
137 test_util::assert_hash(all, test_util::LOW_2_3);
138
139 let mut iter: Recovery = result.recovery_iter();
140 let mut all = Vec::new();
141 all.push(iter.next().unwrap());
142 all.push(iter.next().unwrap());
143 all.push(iter.next().unwrap());
144 assert!(iter.next().is_none());
145 test_util::assert_hash(all, test_util::LOW_2_3);
146 }
147
148 #[test]
149 fn encoder_result_size_hint() {
150 let original = test_util::generate_original(2, 1024, 123);
151 let mut encoder = ReedSolomonEncoder::new(2, 3, 1024).unwrap();
152
153 for original in &original {
154 encoder.add_original_shard(original).unwrap();
155 }
156
157 let result: EncoderResult = encoder.encode().unwrap();
158
159 let mut iter: Recovery = result.recovery_iter();
160
161 assert_eq!(iter.len(), 3);
162
163 assert!(iter.next().is_some());
164 assert!(iter.next().is_some());
165 assert_eq!(iter.len(), 1);
166
167 assert!(iter.next().is_some());
168 assert_eq!(iter.len(), 0);
169
170 assert!(iter.next().is_none());
171 assert_eq!(iter.len(), 0);
172 }
173}