pub struct RunlengthCodec {
#[allow(non_snake_case)]
pub rle_val : u64,
pub shift_up_1: bool }
impl RunlengthCodec {
pub fn encode(&self, input: impl Iterator<Item=u64>) -> Vec<u64>{
let mut encoded: Vec<u64> = Vec::new();
let mut runlen = 0;
for x in input {
if x == self.rle_val {
runlen += 1;
}
else {
if runlen > 0 {
let val = if self.shift_up_1{ self.rle_val+1 } else { self.rle_val};
encoded.push(val);
encoded.push(runlen);
runlen = 0;
}
if self.shift_up_1{
encoded.push(x+1); } else {
encoded.push(x); }
}
}
if runlen >0 {
let val = if self.shift_up_1{ self.rle_val+1 } else { self.rle_val};
encoded.push(val);
encoded.push(runlen);
}
encoded
}
pub fn decode(&self, input: Vec<u64>) -> Vec<u64>{
let mut decoded = Vec::with_capacity(input.len()); let mut iii = input.iter();
while let Some(&item) = iii.next() {
let adjusted_item = if self.shift_up_1 { item -1} else {item};
if adjusted_item == (self.rle_val) {
let runlen = *iii.next().unwrap(); for _ in 0..runlen {
decoded.push(self.rle_val); }
} else {
decoded.push(adjusted_item);
}
}
decoded
}
}
#[cfg(test)]
mod test {
use crate::busz::runlength_codec::RunlengthCodec;
#[test]
fn test_encode_decode_single_run(){
let c = RunlengthCodec { rle_val: 0, shift_up_1: true };
let plain = vec![0,0,0];
let enc = c.encode(plain.clone().into_iter());
assert!(plain.len()> enc.len());
let dec = c.decode(enc);
assert_eq!(plain, dec)
}
#[test]
fn test_encode_decode_no_run(){
let c = RunlengthCodec { rle_val: 0, shift_up_1: true };
let plain = vec![1,2,1];
let enc = c.encode(plain.clone().into_iter());
assert!(plain.len()== enc.len());
let dec = c.decode(enc);
assert_eq!(plain, dec)
}
#[test]
fn test_encode_decode_minxed_run(){
let c = RunlengthCodec { rle_val: 0, shift_up_1: true };
let plain = vec![1,0,0, 2,0,1,0];
let enc = c.encode(plain.clone().into_iter());
assert!(plain.len()< enc.len());
let dec = c.decode(enc);
assert_eq!(plain, dec)
}
#[test]
fn test_encode_decode_minxed_run_rle1(){
let c = RunlengthCodec { rle_val: 1, shift_up_1: true };
let plain = vec![0,1,1, 1,1, 0];
let enc = c.encode(plain.clone().into_iter());
let dec = c.decode(enc);
assert_eq!(plain, dec)
}
#[test]
fn test_encode_decode_minxed_run_rle1_1(){
let c = RunlengthCodec { rle_val: 1 , shift_up_1: true};
let plain = vec![0,1,1,];
let enc = c.encode(plain.clone().into_iter());
let dec = c.decode(enc);
assert_eq!(plain, dec)
}
#[test]
fn test_encode_decode_no_shift(){
let c = RunlengthCodec { rle_val: 0 , shift_up_1: false};
let plain = vec![0,0,1,1,];
let enc = c.encode(plain.clone().into_iter());
let dec = c.decode(enc);
assert_eq!(plain, dec)
}
#[test]
fn test_encode_decode_no_shift_2(){
let c = RunlengthCodec { rle_val: 1 , shift_up_1: false};
let plain = vec![0,0,1,1,];
let enc = c.encode(plain.clone().into_iter());
let dec = c.decode(enc);
assert_eq!(plain, dec)
}
}