mavinspect 0.1.0-alpha2

MAVInspect is a CLI tool and a library to parse and inspect MAVLink protocol XML definitions
Documentation
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};

use crate::proto::mavlink_messages_v1 as proto;
use crate::protocol::{errors::ProtoImportError, Deprecated, MessageField};

/// Type of MAVLink message ID
pub type MessageId = u32;

/// MAVLink message
#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Message {
    /// Unique message ID.
    id: MessageId,
    /// Message name (expected to be unique).
    name: String,
    /// Message description.
    description: String,
    /// List of message fields.
    fields: Vec<MessageField>,
    /// Whether this message definition is in work in progress status.
    wip: bool,
    /// Deprecation status.
    deprecated: Option<Deprecated>,
    /// Dialect name where this message was defined.
    defined_in: Option<String>,
}

impl Message {
    /// Default constructor
    ///
    /// # Arguments
    ///
    /// * `id` - unique message ID.
    /// * `name` - message name.
    /// * `description` - message description.
    /// * `fields` - list of message fields.
    /// * `wip` - work in progress status.
    /// * `deprecated` - deprecation status.
    /// * `defined_in` - name of the dialect where message was defined.
    pub fn new(
        id: MessageId,
        name: String,
        description: String,
        fields: Vec<MessageField>,
        wip: bool,
        deprecated: Option<Deprecated>,
        defined_in: Option<String>,
    ) -> Self {
        Self {
            id,
            name,
            description,
            fields,
            wip,
            deprecated,
            defined_in,
        }
    }

    /// Converts to Protobuf [`proto::Message`].
    pub fn to_proto(&self) -> proto::Message {
        proto::Message {
            id: self.id,
            name: self.name.clone(),
            description: self.description.clone(),
            fields: self.fields.iter().map(MessageField::to_proto).collect(),
            wip: self.wip,
            deprecated: self.deprecated.as_ref().map(|depr| depr.to_proto()),
            defined_in: self.defined_in.clone(),
        }
    }

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

        for field in &proto.fields {
            fields.push(MessageField::from_proto(field)?);
        }

        Ok(Self {
            id: proto.id as MessageId,
            name: proto.name.clone(),
            description: proto.description.clone(),
            fields,
            wip: proto.wip,
            deprecated: match &proto.deprecated {
                None => None,
                Some(deprecated) => Some(Deprecated::from_proto(deprecated)?),
            },
            defined_in: proto.defined_in.clone(),
        })
    }

    /// Unique message ID within dialect
    pub fn id(&self) -> MessageId {
        self.id
    }

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

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

    /// List of message fields
    pub fn fields(&self) -> &Vec<MessageField> {
        &self.fields
    }

    /// Work in progress status
    pub fn wip(&self) -> bool {
        self.wip
    }

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

    /// Dialect name where this message was defined.
    pub fn defined_in(&self) -> &Option<String> {
        &self.defined_in
    }
}