1mod fountain;
8
9use std::marker::PhantomData;
10
11use fedimint_core::encoding::{Decodable, Encodable};
12pub use fountain::Fragment;
13
14pub struct FountainEncoder {
15 encoder: fountain::Encoder,
16}
17
18impl FountainEncoder {
19 pub fn new(encodable: impl Encodable, max_fragment_length: usize) -> Self {
20 Self {
21 encoder: fountain::Encoder::new(
22 encodable.consensus_encode_to_vec().as_slice(),
23 max_fragment_length,
24 ),
25 }
26 }
27
28 pub fn next_fragment(&mut self) -> Fragment {
30 self.encoder.next_fragment()
31 }
32}
33
34pub struct FountainDecoder<E: Decodable> {
36 decoder: fountain::Decoder,
37 _pd: PhantomData<E>,
38}
39
40impl<E: Decodable> Default for FountainDecoder<E> {
41 fn default() -> Self {
42 Self {
43 decoder: fountain::Decoder::default(),
44 _pd: PhantomData,
45 }
46 }
47}
48
49impl<E: Decodable> FountainDecoder<E> {
50 pub fn add_fragment(&mut self, fragment: &Fragment) -> Option<E> {
54 if let Some(Some(d)) = self
55 .decoder
56 .receive(fragment.clone())
57 .transpose()? .ok()
59 .map(|b| Decodable::consensus_decode_whole(&b, &Default::default()).ok())
60 {
61 return Some(d);
62 }
63
64 self.decoder = fountain::Decoder::default();
66
67 None
68 }
69}
70
71#[cfg(test)]
72mod tests;