1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
//! A lightweight binary framing protocol library.
//!
//! This crate provides a minimal, allocation-free framing layer
//! designed for embedded and resource-constrained environments.
//! It focuses on deterministic binary encoding, checksum validation,
//! and zero-copy decoding.
//!
//! # Architecture Overview
//!
//! - **[`Validator`]**
//! Defines CRC algorithms used to validate frames.
//!
//! - **[`DjiValidator`]**
//! A concrete validator using DJI-compatible CRC8 and CRC16.
//!
//! - **[`Marshaler`]**
//! Describes how a typed payload is serialized into bytes and
//! deserialized from raw payload data.
//!
//! - **[`Messager`]**
//! Implements frame packing and unpacking, combining framing,
//! validation, and payload marshaling.
//!
//! - **[`RawFrame`]**
//! A validated, zero-copy view of a decoded frame.
//!
//! - **[`RemoteControl`]** (optional)
//! A helper for encoding and decoding remote control messages.
//!
//! # Typical Usage
//!
//! 1. Implement [`Marshaler`] for your message types
//! 2. Create a [`Messager`] with a chosen [`Validator`]
//! 3. Use [`pack`](Messager::pack) to encode frames
//! 4. Use [`unpack`](Messager::unpack) to decode frames into [`RawFrame`]
//! 5. Use [`Marshaler`] to convert [`RawFrame`] payloads to typed messages
//! 6. Optionally, use [`RemoteControl`] for handling remote control data
//!
//! # Example
//!
//! ```rust
//! # use rm_frame::{Marshaler, MarshalerError, Messager, DjiValidator};
//! # type Error = Box<dyn core::error::Error>;
//! // Define a custom message type and implement Marshaler for it
//! struct MyMessage {
//! value: u32,
//! }
//!
//! impl Marshaler for MyMessage {
//! const CMD_ID: u16 = 0x1234;
//! const PAYLOAD_SIZE: u16 = 4;
//!
//! // If called manually, the caller must ensure that the destination
//! // buffer is large enough to hold the serialized payload.
//! fn marshal(&self, buf: &mut [u8]) -> Result<usize, MarshalerError> {
//! buf[..4].copy_from_slice(&self.value.to_le_bytes());
//! Ok(4)
//! }
//!
//! fn unmarshal(buf: &[u8]) -> Result<Self, MarshalerError> {
//! Ok(Self {
//! value: u32::from_le_bytes([buf[0], buf[1], buf[2], buf[3]]),
//! })
//! }
//! }
//!
//! # fn main() -> Result<(), Error> {
//! let mut buffer = [0u8; 64];
//! let mut msger = Messager::<DjiValidator>::new( /* seq: */ 0 );
//!
//! let msg = MyMessage { value: 38 };
//!
//! let packed_len = msger.pack(&msg, &mut buffer)?; // seq++
//! println!("Packed Frame Length: {}", packed_len);
//!
//! let (decoded_msg, consumed): (MyMessage, _) = msger.unmarshal(&buffer)?;
//! assert_eq!(consumed, packed_len);
//! assert_eq!(decoded_msg.value, 38);
//!
//! let msg = MyMessage { value: 42 };
//!
//! let packed_len = msger.pack(&msg, &mut buffer)?; // seq++
//! println!("Packed Frame Length: {}", packed_len);
//!
//! let (raw_frame, consumed) = msger.unpack(&buffer)?;
//! assert_eq!(consumed, packed_len);
//! assert_eq!(raw_frame.cmd_id(), MyMessage::CMD_ID);
//! assert_eq!(raw_frame.sequence(), 1);
//!
//! let decoded_msg = MyMessage::unmarshal(raw_frame.payload())?;
//! assert_eq!(decoded_msg.value, 42);
//! # Ok(())
//! # }
//! ```
//!
//! > [`RemoteControl`]'s Example See [README.md][README] for details.
//!
//! ---
//!
//! # Frame Layout
//!
//! ```text
//! +--------+--------+--------+--------+--------+---------+--------+
//! | SOF | LEN | SEQ | CRC8 | CMD_ID | DATA | CRC16 |
//! +--------+--------+--------+--------+--------+---------+--------+
//! | 1 byte | 2 byte | 1 byte | 1 byte | 2 byte | N bytes | 2 byte |
//! +--------+--------+--------+--------+--------+---------+--------+
//! ```
//!
//! # Protocol Source
//!
//! See RoboMaster Resources Hub for official documentation and protocol details:
//! [RMU Communication Protocol](https://bbs.robomaster.com/wiki/20204847/811363)
//!
//! # Features
//!
//! - `defmt`: Derives `defmt::Format` on error types and
//! key enums for embedded structured logging.
//! - `remote`: Adds support for encoding and decoding remote control messages,
//! including switch states and joystick positions.
//!
//! ---
//!
//! # License
//!
//! This crate is licensed under the MIT License or the Apache License (Version 2.0).
//! See `LICENSE-MIT` and `LICENSE-APACHE` files in the repository for details.
//!
//! [README]: https://github.com/Salfa-04/rm-proto
//!
pub use calculate as calc_dji8;
pub use calculate as calc_dji16;
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;