mavspec 0.6.7

A set of code generation utilities for MAVLink protocol.
Documentation
//! # MAVSpec
//!
//! <span style="font-size:24px">[πŸ‡ΊπŸ‡¦](https://mavka.gitlab.io/home/a_note_on_the_war_in_ukraine/)</span>
//! [![`repository`](https://img.shields.io/gitlab/pipeline-status/mavka/libs/mavspec.svg?branch=main&label=repository)](https://gitlab.com/mavka/libs/mavspec)
//! [![`crates.io`](https://img.shields.io/crates/v/mavspec.svg)](https://crates.io/crates/mavspec)
//! [![`docs.rs`](https://img.shields.io/docsrs/mavspec.svg?label=docs.rs)](https://docs.rs/mavinspect/latest/mavspec/)
//! [![`issues`](https://img.shields.io/gitlab/issues/open/mavka/libs/mavspec.svg)](https://gitlab.com/mavka/libs/mavspec/-/issues/)
//!
//! Bindings and code-generation toolchain for [MAVLink](https://mavlink.io/en/) protocol based on
//! [MAVInspect](https://crates.io/crates/mavinspect).
//!
//! This library is I/O agnostic and does not provide any abstractions for transferring MAVLink
//! messages. If you want to communicate with MAVLink devices, use
//! [Mavio](https://crates.io/crates/mavio) for embedded devices and simple tasks or
//! [Maviola](https://crates.io/crates/maviola) for advanced I/O in `std` environments (for ground
//! control stations, communication layers, and so on).
//!
//! MAVSpec is a part of [Mavka](https://mavka.gitlab.io/home/) toolchain
//!
//! # Features
//!
//! This library provides MAVLink abstractions to work with MAVLink messages and dialects.
//!
//! It also provides a set of additional tools to work with MAVLink
//! [microservices](https://mavlink.io/en/services/). Basic microservices support involves
//! generation of sub-dialects which include only required entities. For some microservices, like
//! mission, additional utilities are provided.
//!
//! # Rust
//!
//! All Rust-related bindings can be found in [`rust`] module.
//!
//! <section class="warning">
//!
//! This library is mostly focused on Rust bindings. At the moment, we support other languages using
//! [specta](https://specta.dev).
//! </section>
//!
//! By default, this library pre-builds standard MAVLink dialects. However, when
//! `--no-default-features` is set, then you should enable one of the dialects Cargo features as
//! described below.
//!
//! ## Dialects
//!
//! Standard MAVLink dialect can be bundled with MAVSpec. This can be enabled by the corresponding
//! feature flags.
//!
//! * [`minimal`]((https://mavlink.io/en/messages/minimal.html)) β€” minimal dialect required to
//!   expose your presence to other MAVLink devices.
//! * [`standard`](https://mavlink.io/en/messages/standard.html) β€” a superset of `minimal` dialect,
//!   that expected to be used by almost all flight stack.
//! * [`common`](https://mavlink.io/en/messages/common.html) β€” minimum viable dialect with most of
//!   the features, a building block for other future-rich dialects.
//! * [`ardupilotmega`](https://mavlink.io/en/messages/common.html) β€” feature-full dialect used by
//!   [ArduPilot](http://ardupilot.org). In most cases this dialect is the go-to choice if you want
//!   to recognize almost all MAVLink messages used by existing flight stacks.
//! * [`all`](https://mavlink.io/en/messages/all.html) β€” meta-dialect which includes all other
//!   standard dialects including those which were created for testing purposes. It is guaranteed
//!   that namespaces of the dialects in `all` family do not collide.
//! * Other dialects from MAVLink XML [definitions](https://github.com/mavlink/mavlink/tree/master/message_definitions/v1.0):
//!   `asluav`, `avssuas`, `csairlink`, `cubepilot`, `development`, `icarous`, `matrixpilot`,
//!   `paparazzi`, `ualberta`, `uavionix`. These do not include `python_array_test` and `test`
//!   dialects which should be either generated manually or as a part of `all` meta-dialect.
//!
//! <section class="warning">
//!
//! To bundle MAVLink entities for Rust, you should enable `rust-dialects` feature flag.
//! </section>
//!
//! For example:
//!
//! ```rust
//! # #[cfg(not(all(feature = "dlct-common", feature = "std", feature = "rust-dialects")))]
//! # fn main() {}
//! # #[cfg(all(feature = "dlct-common", feature = "std", feature = "rust-dialects"))]
//! # fn main() {
//! use mavspec::rust::dialects::common as dialect;
//! use dialect::{Common, messages::Heartbeat};
//!
//! let message = Heartbeat {
//!     /* construct a message */
//!     # ..Heartbeat::default()
//! };
//!
//! // Use message with dialect enum:
//! let dialect_message = Common::Heartbeat(message);
//!
//! // Dialect message:
//! match dialect_message {
//!     Common::Heartbeat(msg) => {
//!         /* process heartbeat */
//!     }
//!     /* process other messages */
//!     # _ => { unreachable!(); }
//! };
//! # }
//! ```
//!
//! ## Default dialect
//!
//! When standard MAVLink dialects are used and at least `minimal` Cargo feature is enabled, this
//! library exposes [`default_dialect`](rust::default_dialect) and
//! [`DefaultDialect`](rust::DefaultDialect) entities that allow to access the most feature-rich
//! enabled MAVLink dialect.
//!
//! The sequence of default dialects is the following (in the order of the increased completeness):
//!
//! - [`minimal`](rust::dialects::minimal) β€” enabled by `dlct-minimal` feature flag
//! - [`standard`](rust::dialects::standard) β€” enabled by `dlct-standard` feature flag
//! - [`common`](rust::dialects::common) β€” enabled by `dlct-common` feature flag
//! - [`ardupilotmega`](rust::dialects::ardupilotmega) β€” enabled by `dlct-ardupilotmega` feature flag
//! - [`all`](rust::dialects::all) β€” enabled by `dlct-all` feature flag
//!
//! ## Microservices
//!
//! MAVSpec allows to generate additional structures tailored for MAVLink
//! [microservices](https://mavlink.io/en/services/). Each microservice is a subdialect with only
//! those messages and enums which are necessary.
//!
//! Microservices are generated only for a default dialect and available as [`rust::microservices`].
//! To generate microservice subdialects use the corresponding `msrv-*` feature flag.
//!
//! MAVSpec also provides additional utils to work with MAVLink microservices. These tools can be
//! enabled by `msrv-utils-*` feature flags and available in [`rust::microservices::utils`] module.
//!
//! <section class="warning">
//!
//! `msrv-utils-*` are considered unstable for now! Use `unstable` feature flag to enable them.
//! </section>
//!
//! ## Metadata
//!
//! You may want to add additional metadata to MAVLink entities such as a name of enum or the list
//! of its variants. In that case you may enable `metadata` feature flag.
//!
//! ```rust
//! # #[cfg(not(all(feature = "dlct-common", feature = "std", feature = "rust-dialects", feature = "metadata")))]
//! # fn main() {}
//! # #[cfg(all(feature = "dlct-common", feature = "std", feature = "rust-dialects", feature = "metadata"))]
//! # fn main() {
//! use mavspec::rust::default_dialect::enums::MavCmd;
//!
//! println!("Enum name: {}", MavCmd::name());
//!
//! for entry in MavCmd::entries() {
//!   println!("Entry {:?} has a value {}", entry, entry.value());
//! }
//! # }
//! ```
//!
//! # Message definitions
//!
//! It is possible to bundle message definitions generated by [MAVInspect](https://crates.io/crates/mavinspect)
//! into [`definitions`] module. This can be useful for ground control stations that require to present the
//! user with the descriptions of MAVLink entities.
//!
//! To enable definitions bundling use `definitions` feature flag.
//!
//! For example:
//!
//!```rust
//! # #[cfg(not(all(feature = "dlct-common", feature = "std", feature = "rust-dialects", feature = "definitions")))]
//! # fn main() {}
//! # #[cfg(all(feature = "dlct-common", feature = "std", feature = "rust-dialects", feature = "definitions"))]
//! # fn main() {
//! let protocol = mavspec::definitions::protocol();
//! let mav_cmd = protocol
//!     .default_dialect()
//!     .unwrap()
//!     .get_enum_by_name("MAV_CMD")
//!     .unwrap();
//!
//! println!("MAV_CMD\n: {}", mav_cmd.description());
//! # }
//!```
//!
//! <section class="warning">
//!
//! Message definitions available only with `std` feature enabled. Otherwise, this will cause build
//! to fail.
//! </section>
//!
//! # Generation
//!
//! This library can generate custom dialects from XML definitions.
//!
//! Check [`rust::gen`] for details.
//!
//! ## Fingerprints
//!
//! MAVInspect may skip code re-generation if dialects haven't changed. It uses 64-bit CRC fingerprint to monitor
//! changes. Set `fingerprints` feature flag to enable this behavior.
//!
//! This feature is useful for reducing build time during development and CI runs. Make sure that your releases are
//! clean and do not depend on fingerprints.
//!
//! # Caveats
//!
//! The API is straightforward and generally stable, however, incorrect use of certain features
//! may lead to issues during deployment and development.
//!
//! ## Binary Size
//!
//! For small applications that use only a small subset of messages, avoid using dialect enums as
//! they contain all message variants. Instead, decode messages directly from frames:
//!
//! This will help compiler to throw away unnecessary pieces of code.
//!
//! Additionally, you may use [`microservices`](rust::microservices) to reduce API surface you are
//! interacting with.
//!
//! ## Unstable Features
//!
//! Certain features are considered unstable and available only when `unstable` feature flag is
//! enabled. Unstable features are marked with <sup>`⍚`</sup> and are may be changed in futures
//! versions.
//!
//! ## Incompatible Features
//!
//! - [Specta](https://crates.io/crates/specta) requires `std` feature to be enabled.
//! - [`definitions`] requires `std` feature to be enabled.
//!
//! # Feature Flags
//!
//! In most of the cases you will be interested in dialect features, `msrv-*`, `msrv-utils-*`
//! feature families, and `alloc` / `std` target specification. However, a more fine-grained control
//! may be required.
//!
#![cfg_attr(feature = "std", doc = document_features::document_features!())]
//
#![warn(missing_docs)]
#![deny(rustdoc::broken_intra_doc_links)]
#![doc(
    html_logo_url = "https://gitlab.com/mavka/libs/mavspec/-/raw/main/avatar.png?ref_type=heads",
    html_favicon_url = "https://gitlab.com/mavka/libs/mavspec/-/raw/main/avatar.png?ref_type=heads"
)]
#![cfg_attr(not(feature = "std"), no_std)]

#[cfg(feature = "alloc")]
extern crate alloc;
extern crate core;

#[cfg(feature = "definitions")]
#[doc(inline)]
pub use mavlink_message_definitions as definitions;
#[cfg(feature = "rust")]
pub mod rust;

#[cfg(all(feature = "specta", not(feature = "std")))]
compile_error!(
    "Specta support is currently available only for `std` targets! Add the ` std ` feature."
);

#[cfg(all(feature = "definitions", not(feature = "std")))]
compile_error!(
    "Message definitions support is currently available only for `std` targets! Add the ` std ` feature."
);