asterix_parser 0.1.1

Playground do Protocolo ASTERIX
Documentation
pub mod dataitems;
pub mod datatypes;

use custom_error::custom_error;
use crate::asterix::message::AsterixMessageParseError;

custom_error!{pub DataTypeError
    InvalidDataTypeConversion{type_name: String} = "It was provided an invalid data type for conversion for attribute {type_name}",
}

fn find_repetitive_len(len_octets: &[u8]) -> Result<usize, AsterixMessageParseError> {
    if len_octets.len() > 2 {
        return Err(AsterixMessageParseError::InvalidRepetitiveFieldLength { size: len_octets.len() })
    }

    let mut len_octets_array: [u8; 2] = [0, 0];
    if len_octets.len() == 1  {
        len_octets_array[1] = len_octets[0];
    } else {
        len_octets_array[0] = len_octets[0];
        len_octets_array[1] = len_octets[1];
    }

    let len = u16::from_be_bytes(len_octets_array);
    Ok(len as usize)
}

macro_rules! get_extensible_data_item_length {
    ($octets:expr, $start_index:expr) => {
        {
            use bitvec::prelude::*;
            let mut len :usize = 1;
            // todo: fix length calculation
            let mut current_index = $start_index;
            let mut octet = $octets[current_index];
        
            loop {
                let octet_bits = octet.view_bits::<Lsb0>().to_bitvec();
                let is_fx_set = octet_bits[0];
                if is_fx_set {
                    len = len + 1;
                    current_index = current_index + 1;
                    octet = $octets[current_index];
                } else {
                    break;
                }
            }

            Ok(len)
        }
    }   
}

macro_rules! get_repetitive_data_item_length {
    ($octets:expr, $start_index:expr, $attributes:expr) => { 
        {
            let len: usize = $start_index + $attributes[0].octets_len as usize; // First attribute is repetitive byte length

            let len_octets = $octets[$start_index..len].iter().clone().as_slice();        
            let repetitive_factor = match common::find_repetitive_len(len_octets) {
                Ok(s) => s,
                Err(e) => return Err(e),
            };

            let mut repetitive_block_length = len_octets.len();
            let mut variable_len = 0 as usize;
            let mut last_field = 1 as u8;   
            for attribute in $attributes {
                if attribute.field !=  last_field {
                    variable_len = variable_len + attribute.octets_len as usize;
                    last_field = attribute.field;
                }
            }
            repetitive_block_length = repetitive_block_length + (variable_len * repetitive_factor as usize);

            Ok(repetitive_block_length)
        } as Result<usize, AsterixMessageParseError>
    }
}


pub(crate) use get_extensible_data_item_length;
pub(crate) use get_repetitive_data_item_length;