mavinspect 0.2.4

Library for parsing MAVLink XML definitions
Documentation
MAVInspect
==========

Rust library for parsing [MAVLink](https://mavlink.io/en/) XML definitions.

<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/mavinspect.svg?branch=main&label=repository)](https://gitlab.com/mavka/libs/mavinspect)
[![`crates.io`](https://img.shields.io/crates/v/mavinspect.svg)](https://crates.io/crates/mavinspect)
[![`docs.rs`](https://img.shields.io/docsrs/mavinspect.svg?label=docs.rs)](https://docs.rs/mavinspect/latest/mavinspect/)
[![`issues`](https://img.shields.io/gitlab/issues/open/mavka/libs/mavinspect.svg)](https://gitlab.com/mavka/libs/mavinspect/-/issues/)

<details>
<summary>
More on MAVLink
</summary>

MAVLink is a lightweight open protocol for communicating between drones, onboard components and ground control stations.
It is used by such autopilots like [PX4](https://px4.io) or [ArduPilot](https://ardupilot.org/#). MAVLink has simple and
compact serialization model. The basic abstraction is `message` which can be sent through a link (UDP, TCP, UNIX
socket, UART, whatever) and deserialized into a struct with fields of primitive types or arrays of primitive types.
Such fields can be additionally restricted by `enum` variants, annotated with metadata like units of measurements,
default or invalid values.

There are several MAVLink dialects. Official dialect definitions are
[XML files](https://mavlink.io/en/guide/xml_schema.html) that can be found in the MAVlink
[repository](https://github.com/mavlink/mavlink/tree/master/message_definitions/v1.0). Based on `message` abstractions,
MAVLink defines so-called [`microservices`](https://mavlink.io/en/services/) that specify how clients should respond on
a particular message under certain conditions or how they should initiate a particular action.
</details>

This library is a building block for other MAVLink-related tools (code generators, telemetry collectors, IO, etc.). We
intentionally moved everything which is not related to protocol inspection to
other [Mavka](https://mavka.gitlab.io/home/)
project.

<details>
<summary>
What is Mavka?
</summary>

[Mavka](https://mavka.gitlab.io/home/) is a collection of tools to parse, store and communicate MAVLink data written in
Rust. In particular:

* [MAVSpec]https://gitlab.com/mavka/libs/mavspec is responsible for code generation.
* [Mavio]https://gitlab.com/mavka/libs/mavio, a minimalistic library for transport-agnostic MAVLink communication
  written in Rust. It supports `no-std` (and `no-alloc`) targets and focuses on **stateless** parts of MAVLink protocol.
* [Maviola]https://gitlab.com/mavka/libs/maviola is a MAVLink communication library based on `Mavio` that
  provides a high-level interface for MAVLink messaging and takes care about **stateful** features of the protocol:
  sequencing, message time-stamping, automatic heartbeats, simplifies message signing, and so on.

</details>

This project respects [`semantic versioning`](https://semver.org). As allowed by specification, breaking changes may be
introduced in minor releases until version `1.0.0` is reached. However, we will keep unstable features under the
`unstable` feature flag whenever possible.

Install
-------

Install MAVSpec with cargo:

```shell
cargo add mavinspect
```

Usage
-----

Parse standard and custom XML definitions from [`./message_definitions`](./message_definitions):

```rust
use mavinspect::parser::Inspector;

fn main() {
    // Instantiate inspector and load list of XML definitions
    let inspector = Inspector::builder()
        .set_sources(&[
            "./message_definitions/standard",
            "./message_definitions/extra",
        ])
        .build()
        .unwrap();
    
    // Parse all XML definitions
    let protocol = inspector.parse().unwrap();
    
    // Get `minimal` dialect
    let minimal = protocol.dialects().get("minimal").unwrap();
    
    // Get `HEARTBEAT` message
    let heartbeat = minimal.get_message_by_name("HEARTBEAT").unwrap();
    println!("\n`HEARTBEAT` message: {:#?}", heartbeat);
}
```

See [examples](#examples) and [`API documentation`](https://docs.rs/mavinspect/latest/mavinspect/) for advanced usage.

### Dialects Naming

To avoid collision between similar dialect names like `SomeDialect` and `some_dialect` in libraries which use
MAVInspect for code generation, we match names up to `lower_snake_case`. This means that `SomeDialect`,
`SOME_DIALECT`, and `some_dialect` will be considered the same, while `somedialect` will be considered as a
different dialect.

Examples
--------

- [`parser`]./examples/parser.rs β€” parse XML definitions.
  ```shell
  cargo run --example parser --features=serde
  ```

Roadmap
-------

API is considered relatively stable but certain advanced features are yet to be developed. However, most of these
features are nice to have, rather than something necessary to consider this library complete.

Milestone [`v1`](https://gitlab.com/mavka/libs/mavinspect/-/milestones/1) contains features considered necessary to
reach stable version `1.0.0`.

There are
several [experimental features](https://gitlab.com/mavka/libs/mavinspect/-/issues/?label_name%5B%5D=experimental)
which may or may be released. Most of them are related to the
[`gRPC`](https://gitlab.com/mavka/libs/mavinspect/-/milestones/2) milestone.

[Propositions](https://gitlab.com/mavka/spec/libs/mavinspect/-/issues) and
[pull-requests](https://gitlab.com/mavka/spec/libs/mavinspect/-/merge_requests) are welcomed.

Other MAVLink Tools
-------------------

First of all, there is an official MAVLink client for Rust worth mentioning:
[`rust-mavlink`](https://github.com/mavlink/rust-mavlink). One of the reasons behind writing *this* library was the
desire
to decouple parser and code generator into the separate projects.

I was personally inspired by [`gomavlib`](https://github.com/bluenviron/gomavlib) library for MAVLink (Go). I like the
way it is written, and its source code helped me in several cases when official MAVLink documentation wasn't clear
enough.

If you want to autogenerate language bindings and prefer Python, you might be interested in the official
[`mavgen`](https://mavlink.io/en/getting_started/generate_libraries.html#mavgen) code-generation tool. If you are
looking for a router for MAVLink messages, then we suggest [`mavp2p`](https://github.com/bluenviron/mavp2p). If
you want a solution that supports MAVLink microservices, then it worth
checking [`MAVSDK`](https://github.com/mavlink/MAVSDK)
that uses [gRPC](https://grpc.io) API.

MAVLink is almost 15 years old, but the ecosystem around this protocol is still dynamic and developing. Some projects
are
stable and robust, while others are nice and feature-rich but incomplete.

License
-------

> Here we simply comply with the suggested dual licensing according to
> [Rust API Guidelines]https://rust-lang.github.io/api-guidelines/about.html (C-PERMISSIVE).

Licensed under either of

* Apache License, Version 2.0
  ([LICENSE-APACHE]LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
* MIT license
  ([LICENSE-MIT]LICENSE-MIT or http://opensource.org/licenses/MIT)

at your option.

Contribution
------------

Unless you explicitly state otherwise, any contribution intentionally submitted
for inclusion in the work by you, as defined in the Apache-2.0 license, shall be
dual licensed as above, without any additional terms or conditions.