1use eyre::Result;
2use reed_solomon_erasure::galois_8::ReedSolomon;
3
4use crate::{Matrix2D, Matrix3D};
5
6pub trait Codec {
8 fn encode(&self, data: Matrix2D) -> Result<Matrix2D>;
11 fn decode(&self, data: Matrix3D) -> Result<Matrix3D>;
14 fn max_chunks(&self) -> usize;
16}
17
18pub fn new(data_len: usize) -> Result<Box<dyn Codec>> {
19 Ok(Box::new(ReedSolomonCodec::new(data_len)?))
20}
21
22const REED_SOLOMON_MAX_CHUNKS: usize = 32768 * 32768;
23
24struct ReedSolomonCodec {
26 data_len: usize,
27 rs: ReedSolomon,
28}
29
30impl ReedSolomonCodec {
31 fn new(data_len: usize) -> Result<Self> {
33 Ok(Self {
34 data_len,
35 rs: ReedSolomon::new(data_len, data_len)?,
36 })
37 }
38}
39
40impl Codec for ReedSolomonCodec {
41 fn encode(&self, data: Matrix2D) -> Result<Matrix2D> {
44 let original_data_len = data.len();
45 let mut shards = vec![vec![0; self.data_len]; self.data_len];
46 for (i, row) in data.iter().enumerate() {
47 shards[i] = row.clone();
48 }
49 for _i in 0..data.len() {
50 shards.push(vec![0; data[0].len()])
51 }
52 self.rs.encode(&mut shards)?;
53 let encoded_data = shards[original_data_len..].to_vec();
54 Ok(encoded_data)
55 }
56
57 fn decode(&self, _data: Matrix3D) -> Result<Matrix3D> {
60 todo!()
61 }
62
63 fn max_chunks(&self) -> usize {
65 REED_SOLOMON_MAX_CHUNKS
66 }
67}