reed_solomon_16/
decoder_result.rs

1use crate::rate::DecoderWork;
2
3// ======================================================================
4// DecoderResult - PUBLIC
5
6/// Result of decoding. Contains the restored original shards.
7///
8/// This struct is created by [`ReedSolomonDecoder::decode`]
9/// and [`RateDecoder::decode`].
10///
11/// [`RateDecoder::decode`]: crate::rate::RateDecoder::decode
12/// [`ReedSolomonDecoder::decode`]: crate::ReedSolomonDecoder::decode
13pub struct DecoderResult<'a> {
14    work: &'a mut DecoderWork,
15}
16
17impl<'a> DecoderResult<'a> {
18    /// Returns restored original shard with given `index`
19    /// or `None` if given `index` doesn't correspond to
20    /// a missing original shard.
21    pub fn restored_original(&self, index: usize) -> Option<&[u8]> {
22        self.work.restored_original(index)
23    }
24
25    /// Returns iterator over all restored original shards
26    /// and their indexes, ordered by indexes.
27    pub fn restored_original_iter(&self) -> RestoredOriginal {
28        RestoredOriginal::new(self.work)
29    }
30}
31
32// ======================================================================
33// DecoderResult - CRATE
34
35impl<'a> DecoderResult<'a> {
36    pub(crate) fn new(work: &'a mut DecoderWork) -> Self {
37        Self { work }
38    }
39}
40
41// ======================================================================
42// DecoderResult - IMPL DROP
43
44impl<'a> Drop for DecoderResult<'a> {
45    fn drop(&mut self) {
46        self.work.reset_received();
47    }
48}
49
50// ======================================================================
51// RestoredOriginal - PUBLIC
52
53/// Iterator over restored original shards and their indexes.
54///
55/// This struct is created by [`DecoderResult::restored_original_iter`].
56pub struct RestoredOriginal<'a> {
57    ended: bool,
58    next_index: usize,
59    work: &'a DecoderWork,
60}
61
62// ======================================================================
63// RestoredOriginal - IMPL Iterator
64
65impl<'a> Iterator for RestoredOriginal<'a> {
66    type Item = (usize, &'a [u8]);
67    fn next(&mut self) -> Option<(usize, &'a [u8])> {
68        if self.ended {
69            None
70        } else {
71            let mut index = self.next_index;
72            while index < self.work.original_count() {
73                if let Some(original) = self.work.restored_original(index) {
74                    self.next_index = index + 1;
75                    return Some((index, original));
76                }
77                index += 1
78            }
79            self.ended = true;
80            None
81        }
82    }
83}
84
85// ======================================================================
86// RestoredOriginal - CRATE
87
88impl<'a> RestoredOriginal<'a> {
89    pub(crate) fn new(work: &'a DecoderWork) -> Self {
90        Self {
91            ended: false,
92            next_index: 0,
93            work,
94        }
95    }
96}
97
98// ======================================================================
99// TESTS
100
101#[cfg(test)]
102mod tests {
103    use super::*;
104    use crate::{test_util, ReedSolomonDecoder, ReedSolomonEncoder};
105
106    #[test]
107    // DecoderResult::restored_original
108    // DecoderResult::restored_original_iter
109    // RestoredOriginal
110    fn decoder_result() {
111        let original = test_util::generate_original(3, 1024, 0);
112
113        let mut encoder = ReedSolomonEncoder::new(3, 2, 1024).unwrap();
114        let mut decoder = ReedSolomonDecoder::new(3, 2, 1024).unwrap();
115
116        for original in &original {
117            encoder.add_original_shard(original).unwrap();
118        }
119
120        let result = encoder.encode().unwrap();
121        let recovery: Vec<_> = result.recovery_iter().collect();
122
123        decoder.add_original_shard(1, &original[1]).unwrap();
124        decoder.add_recovery_shard(0, recovery[0]).unwrap();
125        decoder.add_recovery_shard(1, recovery[1]).unwrap();
126
127        let result: DecoderResult = decoder.decode().unwrap();
128
129        assert_eq!(result.restored_original(0).unwrap(), original[0]);
130        assert!(result.restored_original(1).is_none());
131        assert_eq!(result.restored_original(2).unwrap(), original[2]);
132        assert!(result.restored_original(3).is_none());
133
134        let mut iter: RestoredOriginal = result.restored_original_iter();
135        assert_eq!(iter.next(), Some((0, original[0].as_slice())));
136        assert_eq!(iter.next(), Some((2, original[2].as_slice())));
137        assert_eq!(iter.next(), None);
138        assert_eq!(iter.next(), None);
139    }
140}