use rand::Rng;
use rlnc::{
RLNCError,
full::{decoder::Decoder, encoder::Encoder, recoder::Recoder},
};
fn main() {
let mut rng = rand::rng();
let original_data_len = 1024 * 10; let piece_count = 32; let original_data: Vec<u8> = (0..original_data_len).map(|_| rng.random()).collect();
let original_data_copy = original_data.clone();
let encoder = Encoder::new(original_data, piece_count).expect("Failed to create RLNC encoder");
println!(
"Initialized Encoder with {} bytes of data, split into {} pieces, each of {} bytes. Each coded piece will be of {} bytes.",
original_data_len,
piece_count,
encoder.get_piece_byte_len(),
encoder.get_full_coded_piece_byte_len()
);
println!(
"Initializing Decoder, expecting {} original pieces of {} bytes each.",
encoder.get_piece_count(),
encoder.get_piece_byte_len()
);
let mut decoder = Decoder::new(encoder.get_piece_byte_len(), encoder.get_piece_count()).expect("Failed to create RLNC decoder");
let num_initial_coded_pieces_from_sender = encoder.get_piece_count() / 2; println!("\nSender generating {num_initial_coded_pieces_from_sender} initial coded pieces...");
let mut pieces_for_recoder = Vec::new();
for i in 0..num_initial_coded_pieces_from_sender {
let coded_piece = encoder.code(&mut rng);
pieces_for_recoder.extend_from_slice(&coded_piece);
match decoder.decode(&coded_piece) {
Ok(_) => println!(" Decoded direct piece {}: Useful.", i + 1),
Err(RLNCError::PieceNotUseful) => println!(" Decoded direct piece {}: Not useful.", i + 1),
Err(RLNCError::ReceivedAllPieces) => {
println!(" Decoded direct piece {}: All pieces received, breaking.", i + 1);
break;
}
Err(e) => panic!("Unexpected error during direct decoding: {e:?}"),
}
}
println!("\nInitializing Recoder with {} bytes of received coded pieces.", pieces_for_recoder.len());
let recoder = Recoder::new(pieces_for_recoder, encoder.get_full_coded_piece_byte_len(), encoder.get_piece_count()).expect("Failed to create RLNC recoder");
println!("\nRecoder active. Generating recoded pieces...");
let num_recoded_pieces_to_send = encoder.get_piece_count() * 2; for i in 0..num_recoded_pieces_to_send {
if decoder.is_already_decoded() {
println!(" All necessary pieces received via recoding.");
break;
}
let recoded_piece = recoder.recode(&mut rng);
match decoder.decode(&recoded_piece) {
Ok(_) => println!(" Decoded recoded piece {}: Useful.", i + 1),
Err(RLNCError::PieceNotUseful) => println!(" Decoded recoded piece {}: Not useful.", i + 1),
Err(RLNCError::ReceivedAllPieces) => {
println!(" Decoded recoded piece {}: All pieces received, breaking.", i + 1);
break;
}
Err(e) => panic!("Unexpected error during recoded piece decoding: {e:?}"),
}
}
let mut pieces_for_new_recoder = Vec::new();
for _ in 0..num_initial_coded_pieces_from_sender {
let coded_piece = encoder.code(&mut rng);
pieces_for_new_recoder.extend_from_slice(&coded_piece); }
println!(
"\nInitializing a new Recoder with {} bytes of received coded pieces.",
pieces_for_new_recoder.len()
);
let recoder =
Recoder::new(pieces_for_new_recoder, encoder.get_full_coded_piece_byte_len(), encoder.get_piece_count()).expect("Must be able to build a new recoder");
let num_recoded_pieces_to_send = num_initial_coded_pieces_from_sender / 2; for i in 0..num_recoded_pieces_to_send {
if decoder.is_already_decoded() {
println!(" All necessary pieces received via recoding.");
break;
}
let recoded_piece = recoder.recode(&mut rng);
match decoder.decode(&recoded_piece) {
Ok(_) => println!(" Decoded recoded piece {}: Useful.", i + 1),
Err(RLNCError::PieceNotUseful) => println!(" Decoded recoded piece {}: Not useful.", i + 1),
Err(RLNCError::ReceivedAllPieces) => {
println!(" Decoded recoded piece {}: All pieces received, breaking.", i + 1);
break;
}
Err(e) => panic!("Unexpected error during recoded piece decoding: {e:?}"),
}
}
let mut direct_piece_count = num_initial_coded_pieces_from_sender;
while !decoder.is_already_decoded() {
println!("\nStill need more pieces. Generating direct piece {} from encoder...", direct_piece_count + 1);
let coded_piece = encoder.code(&mut rng);
match decoder.decode(&coded_piece) {
Ok(_) => {
direct_piece_count += 1;
println!(" Decoded direct piece {direct_piece_count}: Useful.");
}
Err(RLNCError::PieceNotUseful) => {
println!(" Decoded direct piece {}: Not useful.", direct_piece_count + 1);
}
Err(RLNCError::ReceivedAllPieces) => {
println!(" All pieces received via direct encoding.");
break;
}
Err(e) => panic!("Unexpected error during direct decoding (post-recoding): {e:?}"),
}
}
println!("\nRetrieving decoded data...");
let decoded_data = decoder.get_decoded_data().expect("Failed to retrieve decoded data after all pieces received");
assert_eq!(original_data_copy, decoded_data);
println!("\nRLNC workflow completed successfully! Original data matches decoded data.");
}