mavinspect 0.1.0-alpha2

MAVInspect is a CLI tool and a library to parse and inspect MAVLink protocol XML definitions
Documentation
use std::collections::HashMap;

#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};

use crate::proto::mavlink_messages_v1 as proto;
use crate::protocol::{Enum, Message, MessageId};

use super::errors::ProtoImportError;

/// MAVLink dialect specification.
#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Dialect {
    name: String,
    version: Option<u8>,
    dialect: Option<u8>,
    messages: HashMap<MessageId, Message>,
    enums: HashMap<String, Enum>,
}

impl Dialect {
    /// Default constructor
    ///
    /// # Arguments
    ///
    /// * `name` dialect name
    /// * `version` dialect version
    /// * `version` dialect version (if provided)
    /// * `messages` map of messages
    /// * `enums` map of enums
    pub fn new(
        name: String,
        version: Option<u8>,
        dialect: Option<u8>,
        messages: HashMap<MessageId, Message>,
        enums: HashMap<String, Enum>,
    ) -> Self {
        Self {
            name,
            version,
            dialect,
            messages,
            enums,
        }
    }

    /// Converts to Protobuf [`proto::Dialect`].
    pub fn to_proto(&self) -> proto::Dialect {
        proto::Dialect {
            name: self.name.clone(),
            version: self.version.map(|ver| ver as u32),
            dialect: self.dialect.map(|dialect| dialect as u32),
            messages: self
                .messages
                .iter()
                .map(|(&id, msg)| (id, msg.to_proto()))
                .collect(),
            enums: self
                .enums
                .iter()
                .map(|(name, enm)| (name.clone(), enm.to_proto()))
                .collect(),
        }
    }

    /// Constructs from Protobuf [`proto::Dialect`].
    pub fn from_proto(proto: &proto::Dialect) -> Result<Self, ProtoImportError> {
        let mut messages = HashMap::new();
        let mut enums = HashMap::new();

        for (&id, message) in &proto.messages {
            messages.insert(id, Message::from_proto(message)?);
        }

        for (name, enm) in &proto.enums {
            enums.insert(name.clone(), Enum::from_proto(enm)?);
        }

        Ok(Self {
            name: proto.name.clone(),
            version: proto.version.map(|v| v as u8),
            dialect: proto.dialect.map(|dialect| dialect as u8),
            messages,
            enums,
        })
    }

    /// Dialect name
    pub fn name(&self) -> &String {
        &self.name
    }

    /// Dialect version
    pub fn version(&self) -> Option<u8> {
        self.version
    }

    /// List of messages
    pub fn messages(&self) -> &HashMap<MessageId, Message> {
        &self.messages
    }

    /// List of enums
    pub fn enums(&self) -> &HashMap<String, Enum> {
        &self.enums
    }
}