jppe 1.1.1

This is a byte stream structured serialization and deserialization library.
Documentation
use crate::std::*;
use crate::ByteOrder;
use crate::{ContainerAttrModifiers, FieldAttrModifiers};
use super::{BorrowByteEncode, ByteEncode};


macro_rules! impls_int {
    ($type:ident, $byte:expr) => {
        impl ByteEncode for $type {
            fn encode(&self, input: &mut Vec<u8>, cattr: Option<&ContainerAttrModifiers>, fattr: Option<&FieldAttrModifiers>)
                where 
                    Self: Sized
            {
                let mut byte_tmp = None;
                let mut value = *self;

                let byteorder = crate::get_byteorder(cattr, fattr);

                if let Some(fr) = fattr {
                    if let Some(length) = fr.length {
                        if length < $byte { byte_tmp = Some(length); }
                    }

                    if let Some(bits) = fr.bits {
                        let mut bits = bits as u128;
                                                
                        for _i in 0..$type::BITS {
                            if bits & 0x01 == 0 {
                                value <<= 1;
                                bits >>= 1;
                            }
                        }

                        if !fr.bits_start {
                            let byte = ($type::BITS / 8) as usize;
    
                            if input.len() >= byte {
                                if let Ok(v) = <[u8; $byte]>::try_from(&input[input.len() - byte..]) {
                                    let prev_bits = $type::from_be_bytes(v);
                                    value |= prev_bits;
                                    for _ in 0..byte { input.pop(); }    
                                }
                            }    
                        }
                    }
                }
                        
                match byteorder {
                    ByteOrder::Be => {
                        if let Some(byte) = byte_tmp {
                            input.extend(&value.to_be_bytes()[$byte - byte..]);
                        }
                        else {
                            input.extend(value.to_be_bytes());
                        }
                    },
                    ByteOrder::Le => {
                        if let Some(byte) = byte_tmp {
                            input.extend(&value.to_le_bytes()[..byte]);
                        }
                        else {
                            input.extend(value.to_le_bytes());
                        }
                    },
                }            
            }
        }        


        impl BorrowByteEncode for $type {
            fn encode(&self, input: &mut Vec<u8>, cattr: Option<&ContainerAttrModifiers>, fattr: Option<&FieldAttrModifiers>)
                where 
                    Self: Sized
            {
                ByteEncode::encode(self, input, cattr, fattr);
            }
        }
    };
    () => {
        impls_int!(u8, 1);
        impls_int!(u16, 2);
        impls_int!(u32, 4);
        impls_int!(u64, 8);
        impls_int!(usize, (usize::BITS / 8) as usize);
        impls_int!(u128, 16);
        
        impls_int!(i8, 1);
        impls_int!(i16, 2);
        impls_int!(i32, 4);
        impls_int!(i64, 8);
        impls_int!(isize, (usize::BITS / 8) as usize);     
        impls_int!(i128, 16);   
    }
}


impls_int!();


#[cfg(test)]
mod tests {
    use crate::{ContainerAttrModifiers, ByteOrder, FieldAttrModifiers};
    use crate::encode::ByteEncode;

    #[test]
    fn test_encode_int() {
        let value: u16 = 1;

        let mut buf = vec![];
        value.encode(&mut buf, None, None);
        assert_eq!(buf, vec![0, 1]);

        let cattr = ContainerAttrModifiers {
            byteorder: Some(ByteOrder::Le),
            ..Default::default()
        };
        let mut buf = vec![];
        value.encode(&mut buf, Some(&cattr), None);
        assert_eq!(buf, vec![1, 0]);

        let fattr = FieldAttrModifiers {
            byteorder: Some(ByteOrder::Be),
            ..Default::default()
        };

        let mut buf = vec![];
        value.encode(&mut buf, Some(&cattr), Some(&fattr));
        assert_eq!(buf, vec![0, 1]);

        let value: u32 = 1;

        let fattr = FieldAttrModifiers {
            byteorder: Some(ByteOrder::Be),
            length: Some(3),
            ..Default::default()
        };

        let mut buf = vec![];
        value.encode(&mut buf, Some(&cattr), Some(&fattr));
        assert_eq!(buf, vec![0, 0, 1]);

        let fattr = FieldAttrModifiers {
            byteorder: Some(ByteOrder::Le),
            length: Some(3),
            ..Default::default()
        };

        let mut buf = vec![];
        value.encode(&mut buf, Some(&cattr), Some(&fattr));
        assert_eq!(buf, vec![1, 0, 0]);
    }
}