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::{enums::EnumEntry, errors::ProtoImportError, Deprecated};

/// Enum
///
/// MAVLink enum is a special field type. There are two types of enums:
/// - **regular**: value specifies a particular enum option (entry)
/// - **bitmask**: each bit signifies a particular flag
///
/// Enum options (entries) and flags are specified by [`EnumEntry`].
#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Enum {
    name: String,
    description: String,
    entries: HashMap<String, EnumEntry>,
    bitmask: bool,
    deprecated: Option<Deprecated>,
    defined_in: Vec<String>,
}

impl Enum {
    /// Default constructor
    ///
    /// # Arguments
    ///
    /// * `name` - enum name
    /// * `description` - enum description
    /// * `entries` - map of enum entries ([`EnumEntry`])
    /// * `bitmask` - whether this enum is a bitmask
    /// * `deprecated` - deprecation status
    pub fn new(
        name: String,
        description: String,
        entries: HashMap<String, EnumEntry>,
        bitmask: bool,
        deprecated: Option<Deprecated>,
        defined_in: Vec<String>,
    ) -> Self {
        Self {
            name,
            description,
            entries,
            bitmask,
            deprecated,
            defined_in,
        }
    }

    /// Converts to Protobuf [`proto::Enum`].
    pub fn to_proto(&self) -> proto::Enum {
        proto::Enum {
            name: self.name.clone(),
            description: self.description.clone(),
            entries: self
                .entries
                .iter()
                .map(|(name, entry)| (name.clone(), entry.to_proto()))
                .collect(),
            bitmask: self.bitmask,
            deprecated: self.deprecated.as_ref().map(|d| d.to_proto()),
            defined_in: self.defined_in.clone(),
        }
    }

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

        for (name, entry) in &proto.entries {
            entries.insert(name.clone(), EnumEntry::from_proto(entry)?);
        }

        Ok(Self {
            name: proto.name.clone(),
            description: proto.description.clone(),
            entries,
            bitmask: proto.bitmask,
            deprecated: match &proto.deprecated {
                None => None,
                Some(depr) => Some(Deprecated::from_proto(depr)?),
            },
            defined_in: proto.defined_in.clone(),
        })
    }

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

    /// Enum description.
    pub fn description(&self) -> &String {
        &self.description
    }

    /// Vector of enum entries.
    pub fn entries(&self) -> &HashMap<String, EnumEntry> {
        &self.entries
    }

    /// Whether this enum is a bitmask.
    pub fn bitmask(&self) -> bool {
        self.bitmask
    }

    /// Deprecation status.
    pub fn deprecated(&self) -> &Option<Deprecated> {
        &self.deprecated
    }

    /// Dialects in which this enum was defined.
    pub fn defined_in(&self) -> &Vec<String> {
        &self.defined_in
    }
}