mavspec_rust_spec/
dialect.rs

1use crate::types::{DialectId, DialectVersion, MessageId};
2use crate::{IntoPayload, MessageInfo, MessageSpec, Payload, SpecError};
3
4/// Interface for autogenerated or custom MAVLink dialect specification.
5pub trait Dialect: MessageSpec + IntoPayload + Sized + Sync + Send {
6    /// Dialect name as it appears in XML definition.
7    fn name() -> &'static str;
8
9    /// Returns `dialect` identifier as specified in MAVLink [XML definitions](https://mavlink.io/en/guide/xml_schema.html).
10    fn dialect() -> Option<DialectId>;
11
12    /// Minor dialect `version` as specified in MAVLink [XML definitions](https://mavlink.io/en/guide/xml_schema.html).
13    ///
14    /// Corresponds to [`uint8_t_mavlink_version`](https://mavlink.io/en/messages/common.html#HEARTBEAT).
15    ///
16    /// Dialect version appears in some messages like [HEARTBEAT](https://mavlink.io/en/messages/common.html#HEARTBEAT). In
17    /// such cases it is usually not directly set by user.
18    fn version() -> Option<DialectVersion>;
19
20    /// Message specification by `id`.
21    ///
22    /// Clients may access this method to retrieve message specification prior to decoding it from
23    /// payload.
24    ///
25    /// # Errors
26    ///
27    /// Returns [`SpecError::NotInDialect`] if message with specified ID is not supported.
28    fn message_info(id: MessageId) -> Result<&'static dyn MessageSpec, SpecError>;
29
30    /// Decode dialect message from [`Payload`].
31    fn decode(payload: &Payload) -> Result<Self, SpecError>;
32
33    /// Dialect specification.
34    fn spec() -> &'static DialectSpec;
35}
36
37/// Dialect specification.
38#[derive(Clone, Debug)]
39pub struct DialectSpec {
40    name: &'static str,
41    dialect: Option<DialectId>,
42    version: Option<DialectVersion>,
43    messages_info: &'static [MessageInfo],
44}
45
46impl DialectSpec {
47    /// Creates dialect specification.
48    pub const fn new(
49        name: &'static str,
50        dialect: Option<DialectId>,
51        version: Option<DialectVersion>,
52        messages_info: &'static [MessageInfo],
53    ) -> Self {
54        Self {
55            name,
56            dialect,
57            version,
58            messages_info,
59        }
60    }
61
62    /// Dialect name as it appears in XML definition.
63    pub fn name(&self) -> &'static str {
64        self.name
65    }
66
67    /// Returns `dialect` identifier as specified in MAVLink [XML definitions](https://mavlink.io/en/guide/xml_schema.html).
68    pub fn dialect(&self) -> Option<DialectId> {
69        self.dialect
70    }
71
72    /// Minor dialect `version` as specified in MAVLink [XML definitions](https://mavlink.io/en/guide/xml_schema.html).
73    ///
74    /// Corresponds to [`uint8_t_mavlink_version`](https://mavlink.io/en/messages/common.html#HEARTBEAT).
75    ///
76    /// Dialect version appears in some messages like [HEARTBEAT](https://mavlink.io/en/messages/common.html#HEARTBEAT). In
77    /// such cases it is usually not directly set by user.
78    pub fn version(&self) -> Option<DialectVersion> {
79        self.version
80    }
81
82    /// Message specification by `id`.
83    ///
84    /// Clients may access this method to retrieve message specification prior to decoding it from
85    /// payload.
86    ///
87    /// # Errors
88    ///
89    /// Returns [`SpecError::NotInDialect`] if message with specified ID is not supported.
90    pub fn message_info(&self, id: MessageId) -> Result<&MessageInfo, SpecError> {
91        for info in self.messages_info {
92            if info.id() == id {
93                return Ok(info);
94            }
95        }
96        Err(SpecError::NotInDialect(id))
97    }
98}