//! # MAVLink dialects for [MAVSpec](https://crates.io/crates/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/mavlink-dialects.svg)](https://crates.io/crates/mavlink-dialects)
//! [![`docs.rs`](https://img.shields.io/docsrs/mavlink-dialects.svg?label=docs.rs)](https://docs.rs/mavlink-dialects/latest/mavlink-dialects/)
//! [![`issues`](https://img.shields.io/gitlab/issues/open/mavka/libs/mavspec.svg)](https://gitlab.com/mavka/libs/mavspec/-/issues/)
//!
//! [MAVLink](https://mavlink.io/en/) messages bindings based on [MAVInspect](https://crates.io/crates/mavinspect).
//!
//! This library is a part of [MAVSpec](https://crates.io/crates/mavspec) code-generation
//! toolchain and is intended to use alongside with it. However, nothing prevents you from using
//! this crate independently.
//!
//! Since [MAVSpec](https://crates.io/crates/mavspec) is I/O agnostic, it 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).
//!
//! # Usage
//!
//! ```rust
//! # #[cfg(not(feature = "dlct-minimal"))]
//! # fn main() {}
//! # #[cfg(feature = "dlct-minimal")]
//! # fn main() {
//! use dialect::enums::{MavAutopilot, MavModeFlag, MavState};
//! use dialect::messages::Heartbeat;
//! use dialect::Minimal as DialectMessage;
//! use mavlink_dialects::dialects::minimal as dialect;
//! use mavlink_dialects::spec::*;
//!
//! let message = Heartbeat {
//!     autopilot: MavAutopilot::Armazila,
//!     base_mode: MavModeFlag::HIL_ENABLED,
//!     system_status: MavState::Active,
//!     ..Default::default()
//! };
//!
//! // Check that this message indeed supports `MAVLink 1`.
//! assert_eq!(message.min_supported_mavlink_version(), MavLinkVersion::V1);
//!
//! // Encode to MAVLink payload.
//! let payload = message.encode(MavLinkVersion::V2).unwrap();
//! assert_eq!(payload.version(), MavLinkVersion::V2);
//! assert_eq!(payload.id(), message.id());
//!
//! // Decode from MAVLink payload, now without .
//! let dialect_message = DialectMessage::decode(&payload).unwrap();
//! match dialect_message {
//!     DialectMessage::Heartbeat(msg) => {
//!         assert_eq!(msg.id(), Heartbeat::ID);
//!     }
//!     _ => panic!("Unexpected dialect message: {:?}", dialect_message),
//! }
//! # }
//! ```
//!
//! # 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.
//!
//! ## Dialects
//!
//! Standard MAVLink dialect can be bundled with MAVSpec. This can be enabled by the corresponding
//! `dlct-<name>` 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.
//!
//! ### Default Dialect
//!
//! When standard MAVLink dialects are used and at least `dlct-minimal` Cargo feature is enabled,
//! this library exposes [`default_dialect`] and [`DefaultDialect`] entities that allow to access
//! the most feature-rich enabled MAVLink dialect.
//!
//! ## 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. To generate microservice subdialects use `msrv-*`
//! feature flags.
//!
//! At the moment, microservices are only generated for the [`default_dialect`] and, if enabled,
//! are available at [`default_dialect::microservices`] and as `microservices` module of the
//! corresponding default dialect.
//!
//! <section class="warning">
//! We do not recommend to enable microservices for libraries that perform generic MAVLink
//! operations as, if not used properly, this may increase compilation time and binary size.
//! </section>
//!
//! ## Fingerprints
//!
//! MAVSpec 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.
//!
//! ## 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.
//!
//! # Feature Flags
//!
//! In most of the cases you will be interested in `dlct-*` and `msrv-*` 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;

/// <sup>[`mavspec`](https://crates.io/crates/mavspec)</sup>
#[doc(inline)]
pub use mavspec_rust_derive as derive;
/// <sup>[`mavspec`](https://crates.io/crates/mavspec)</sup>
#[doc(inline)]
pub use mavspec_rust_spec as spec;

/// Rust bindings specifications left for compatibility with [MAVSpec](https://crates.io/crates/mavspec).
pub mod rust {
    pub use mavspec_rust_derive as derive;
    pub use mavspec_rust_spec as spec;
}

mod mavlink {
    #[cfg(windows)]
    include!(concat!(env!("OUT_DIR"), "\\mavlink\\mod.rs"));
    #[cfg(not(windows))]
    include!(concat!(env!("OUT_DIR"), "/mavlink/mod.rs"));
}
pub use mavlink::dialects;

#[cfg(feature = "dlct-minimal")]
pub use mavlink::{default_dialect, DefaultDialect};

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