asterix_parser 0.1.1

Playground do Protocolo ASTERIX
Documentation
use serde::{de, Deserialize, Deserializer, Serialize};
use custom_error::custom_error;
use serde_json::{Map, Value};
use strum_macros::{AsRefStr, EnumString};

use super::{structures::{AttributeRule, ConstraintRule}, traits::Describe};

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(tag = "type", rename_all = "lowercase", deny_unknown_fields)]
pub enum Uap {
    Uap { items: Vec<String> },
}

#[derive(Clone)]
pub enum AttributeConstraintLimit {
    SignedInteger { value: i32 },
}

#[derive(AsRefStr, EnumString, Clone)]
pub enum AttributeLsb {
    Integer { value: i32 },
    Real { value: f64 }
}

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(tag = "type", deny_unknown_fields)]
pub enum DataType {
    Integer { value: i32 },
}

#[derive(Debug, PartialEq, Eq, Clone, Copy, Serialize, Deserialize)]
pub enum ConstraintType {
    #[serde(rename = "<")]
    Less,
    #[serde(rename = ">")]
    Great,
    #[serde(rename = "<=")]
    LessOrEqual,
    #[serde(rename = ">=")]
    GreatOrEqual,
}

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(tag = "type", deny_unknown_fields)]
pub enum DenominatorType {
    Pow {
        base: f64,
        exponent: f64,
    }
}

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(tag = "type", deny_unknown_fields)]
pub enum LsbType {
    Integer {
        value: i32
    },
    Div { 
        denominator: DenominatorType,
        numerator: DataType
    }
}

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(tag = "type", deny_unknown_fields)]
pub enum ElementValueType {
    Fx,
    Integer {
        constraints: Vec<ConstraintRule>,
        signed: bool,
    },
    Quantity {
        constraints: Vec<ConstraintRule>,
        lsb: LsbType,
        signed: bool,
        unit: String
    },
    Raw, 
    Regular {size: u8},
    String { variation: String },
    Table {
        values: Vec<(i32, String)>
    },
}

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum DataRecordType {
    Basic,
}

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(tag = "type", deny_unknown_fields)]
pub enum ElementType {
    ContextFree {
        value: ElementValueType
    }
}

impl Default for ElementType {
    fn default() -> Self {
        ElementType::ContextFree { value: ElementValueType::default() }
    }
}

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(tag = "type", deny_unknown_fields)]
pub enum DataItemValueType {
    Element {
        rule: ElementType,
        size: u8,
    },
    Group {
        items: Vec<Option<AttributeItem>>,
    },
    Extended {
        items: Vec<Option<AttributeItem>>,
    },
    Repetitive {
        rep: ElementValueType,
        variation: Box<AttributeValueType>
    },
    Compound {
        fspec: Option<u8>,
        items: Vec<Option<AttributeItem>>,
    },
    Explicit {
        expl: String
    }
}

impl Describe for DataItemValueType {
    fn describe(&self, indent_level: &mut usize) -> String {
        self.get_indented_description(indent_level, String::from("This should not being saw!, from DataItemValueType describe method"))

        /* match &self  {
            DataItemValueType::Element (e) => describe_element(rule, size),
            DataItemValueType::Group { items } => describe_option_attribute_item(&items),
            DataItemValueType::Extended { items } => describe_option_attribute_item(&items),
            DataItemValueType::Repetitive { rep, variation }
                => describe_repetitive(rep, &variation),
            DataItemValueType::Compound { fspec, items } 
                => describe_compound(&fspec, &items),
            DataItemValueType::Explicit { expl } => format!("Explicit: {}", expl)
        }; */
    }
}

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(tag = "type", deny_unknown_fields)]
pub enum DataItemType {
    ContextFree {
        value: DataItemValueType
    },
}

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(tag = "type", deny_unknown_fields)]
pub enum AttributeType {
     ContextFree {
        value: AttributeValueType
     },
}

custom_error!{pub Deserialization
    DeserializationError{attribute: String, error: String}  = "Error deserializing definition of attribute {attribute}, error:{error}",
}

#[derive(Debug, Clone, PartialEq, Serialize)]
#[serde(untagged, deny_unknown_fields)]
pub enum AttributeItem {
    SpareEntry { length: usize, spare: bool },
    AttributeEntry(AttributeRule),
}

impl<'de> Deserialize<'de> for AttributeItem {
    fn deserialize<D>(deserializer: D) -> anyhow::Result<Self, D::Error>
    where
        D: Deserializer<'de>,
    {
        let map = Map::deserialize(deserializer)?;
        let spare: bool;
        let mut spare_length = 0;
        let has_spare = match map.get("spare") {
            Some(v) => {
                spare = serde_json::from_value(v.clone()).unwrap_or(false);
                spare != false
            }
            None => false
        };

        if  has_spare {
            // since we have spare, let us search for the length
            match map.get("length") {
                Some(v) => {
                    spare_length = serde_json::from_value(v.clone()).unwrap_or(0);
                }
                None => Err(Deserialization::DeserializationError {
                            attribute: "AttributeItem::SpareEntry".to_owned(),
                             error: "could not find spare length".to_owned() })
                             .map_err(de::Error::custom)?
            }
        }

        if has_spare {
            Ok(AttributeItem::SpareEntry { length: spare_length, spare: has_spare })
        } else {
            let rest = Value::Object(map);
            let attribute_type =  AttributeRule::deserialize(rest).unwrap_or_default();
            let attribute_item = AttributeItem::AttributeEntry(attribute_type);
            Ok(attribute_item)
        }
    }
}


#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(tag = "type", deny_unknown_fields)]
pub enum AttributeValueType {
    Element {
        rule: ElementType,
        size: u8,
    },
    Group {
        items: Vec<Option<AttributeItem>>,
    },
    Repetitive {
        rep: ElementValueType,
        variation: Box<AttributeValueType>
    },
    Table {
        values: Vec<(i32, String)>
    }
}



impl Default for ElementValueType {
    fn default() -> Self {
        ElementValueType::Raw
    }
}
impl Default for AttributeValueType {
    fn default() -> Self {
        AttributeValueType::Element { rule: ElementType::default(), size: 8 }
    }
}


impl Default for AttributeType {
    fn default() -> Self {
        AttributeType::ContextFree { value: AttributeValueType::default() }
    }
}