Skip to content

Commit 2bf2ac2

Browse files
authored
Use version and dialect tags in code generation (#390)
* use version and dialect tag for code generation * add version and dialect to heartbeat test * emit consts only if they exist in dialect definition
1 parent ae98fec commit 2bf2ac2

4 files changed

Lines changed: 58 additions & 15 deletions

File tree

mavlink-bindgen/src/parser.rs

Lines changed: 52 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ lazy_static! {
4343
pub struct MavProfile {
4444
pub messages: BTreeMap<String, MavMessage>,
4545
pub enums: BTreeMap<String, MavEnum>,
46+
pub version: Option<u8>,
47+
pub dialect: Option<u8>,
4648
}
4749

4850
impl MavProfile {
@@ -125,7 +127,10 @@ impl MavProfile {
125127
/// Emit rust messages
126128
#[inline(always)]
127129
fn emit_msgs(&self) -> Vec<TokenStream> {
128-
self.messages.values().map(|d| d.emit_rust()).collect()
130+
self.messages
131+
.values()
132+
.map(|d| d.emit_rust(self.version.is_some()))
133+
.collect()
129134
}
130135

131136
/// Emit rust enums
@@ -173,6 +178,8 @@ impl MavProfile {
173178
let id_width = format_ident!("u32");
174179

175180
let comment = self.emit_comments(dialect_name);
181+
let mav_minor_version = self.emit_minor_version();
182+
let mav_dialect_number = self.emit_dialect_number();
176183
let msgs = self.emit_msgs();
177184
let deprecations = self.emit_deprecations();
178185
let enum_names = self.emit_enum_names();
@@ -216,6 +223,9 @@ impl MavProfile {
216223
#[cfg(feature = "arbitrary")]
217224
use arbitrary::Arbitrary;
218225

226+
#mav_minor_version
227+
#mav_dialect_number
228+
219229
#(#enums)*
220230

221231
#(#msgs)*
@@ -272,6 +282,24 @@ impl MavProfile {
272282
)
273283
}
274284

285+
#[inline(always)]
286+
fn emit_minor_version(&self) -> TokenStream {
287+
if let Some(version) = self.version {
288+
quote! (pub const MINOR_MAVLINK_VERSION: u8 = #version;)
289+
} else {
290+
TokenStream::default()
291+
}
292+
}
293+
294+
#[inline(always)]
295+
fn emit_dialect_number(&self) -> TokenStream {
296+
if let Some(dialect) = self.dialect {
297+
quote! (pub const DIALECT_NUMBER: u8 = #dialect;)
298+
} else {
299+
TokenStream::default()
300+
}
301+
}
302+
275303
#[inline(always)]
276304
fn emit_mav_message_parse(
277305
&self,
@@ -787,15 +815,15 @@ impl MavMessage {
787815
}
788816

789817
#[inline(always)]
790-
fn emit_const_default(&self) -> TokenStream {
818+
fn emit_const_default(&self, dialect_has_version: bool) -> TokenStream {
791819
let initializers = self
792820
.fields
793821
.iter()
794-
.map(|field| field.emit_default_initializer());
822+
.map(|field| field.emit_default_initializer(dialect_has_version));
795823
quote!(pub const DEFAULT: Self = Self { #(#initializers)* };)
796824
}
797825

798-
fn emit_rust(&self) -> TokenStream {
826+
fn emit_rust(&self, dialect_has_version: bool) -> TokenStream {
799827
let msg_name = self.emit_struct_name();
800828
let id = self.id;
801829
let name = self.name.clone();
@@ -808,7 +836,7 @@ impl MavMessage {
808836

809837
let deser_vars = self.emit_deserialize_vars();
810838
let serialize_vars = self.emit_serialize_vars();
811-
let const_default = self.emit_const_default();
839+
let const_default = self.emit_const_default(dialect_has_version);
812840
let default_impl = self.emit_default_impl();
813841

814842
let deprecation = self.emit_deprecation();
@@ -1006,17 +1034,17 @@ impl MavField {
10061034
}
10071035

10081036
#[inline(always)]
1009-
fn emit_default_initializer(&self) -> TokenStream {
1037+
fn emit_default_initializer(&self, dialect_has_version: bool) -> TokenStream {
10101038
let field = self.emit_name();
10111039
// FIXME: Is this actually expected behaviour??
10121040
if matches!(self.mavtype, MavType::Array(_, _)) {
1013-
let default_value = self.mavtype.emit_default_value();
1041+
let default_value = self.mavtype.emit_default_value(dialect_has_version);
10141042
quote!(#field: #default_value,)
10151043
} else if let Some(enumname) = &self.enumtype {
10161044
let ty = TokenStream::from_str(enumname).unwrap();
10171045
quote!(#field: #ty::DEFAULT,)
10181046
} else {
1019-
let default_value = self.mavtype.emit_default_value();
1047+
let default_value = self.mavtype.emit_default_value(dialect_has_version);
10201048
quote!(#field: #default_value,)
10211049
}
10221050
}
@@ -1190,10 +1218,17 @@ impl MavType {
11901218
}
11911219
}
11921220

1193-
pub fn emit_default_value(&self) -> TokenStream {
1221+
pub fn emit_default_value(&self, dialect_has_version: bool) -> TokenStream {
11941222
use self::MavType::*;
11951223
match self {
1196-
UInt8 | UInt8MavlinkVersion => quote!(0_u8),
1224+
UInt8 => quote!(0_u8),
1225+
UInt8MavlinkVersion => {
1226+
if dialect_has_version {
1227+
quote!(MINOR_MAVLINK_VERSION)
1228+
} else {
1229+
quote!(0_u8)
1230+
}
1231+
}
11971232
Int8 => quote!(0_i8),
11981233
Char => quote!(0_u8),
11991234
UInt16 => quote!(0_u16),
@@ -1205,7 +1240,7 @@ impl MavType {
12051240
Int64 => quote!(0_i64),
12061241
Double => quote!(0.0_f64),
12071242
Array(ty, size) => {
1208-
let default_value = ty.emit_default_value();
1243+
let default_value = ty.emit_default_value(dialect_has_version);
12091244
quote!([#default_value; #size])
12101245
}
12111246
}
@@ -1611,10 +1646,11 @@ pub fn parse_profile(
16111646
include = PathBuf::from(s.replace('\n', ""));
16121647
}
16131648
(Some(&Version), Some(&Mavlink)) => {
1614-
eprintln!("TODO: version {s:?}");
1649+
profile.version =
1650+
Some(s.parse().expect("Invalid minor version number format"));
16151651
}
16161652
(Some(&Dialect), Some(&Mavlink)) => {
1617-
eprintln!("TODO: dialect {s:?}");
1653+
profile.dialect = Some(s.parse().expect("Invalid dialect number format"));
16181654
}
16191655
(Some(Deprecated), _) => {
16201656
deprecated.as_mut().unwrap().note = Some(s);
@@ -1672,6 +1708,9 @@ pub fn parse_profile(
16721708
for enm in included_profile.enums.values() {
16731709
profile.add_enum(enm);
16741710
}
1711+
if profile.version.is_none() {
1712+
profile.version = included_profile.version;
1713+
}
16751714
}
16761715
}
16771716
_ => (),

mavlink-bindgen/tests/definitions/heartbeat.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
<mavlink>
2+
<version>3</version>
3+
<dialect>130</dialect>
24
<messages>
35
<message id="0" name="HEARTBEAT">
46
<field type="uint32_t" name="custom_mode">Custom mode</field>

mavlink-bindgen/tests/snapshots/e2e_snapshots__heartbeat.xml@heartbeat.rs.snap

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ use num_traits::FromPrimitive;
2121
use num_traits::ToPrimitive;
2222
#[cfg(feature = "serde")]
2323
use serde::{Deserialize, Serialize};
24+
pub const MINOR_MAVLINK_VERSION: u8 = 3u8;
25+
pub const DIALECT_NUMBER: u8 = 130u8;
2426
#[derive(Debug, Clone, PartialEq)]
2527
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2628
#[cfg_attr(feature = "arbitrary", derive(Arbitrary))]
@@ -40,7 +42,7 @@ impl HEARTBEAT_DATA {
4042
autopilot: 0_u8,
4143
base_mode: 0_u8,
4244
system_status: 0_u8,
43-
mavlink_version: 0_u8,
45+
mavlink_version: MINOR_MAVLINK_VERSION,
4446
};
4547
#[cfg(feature = "arbitrary")]
4648
pub fn random<R: rand::RngCore>(rng: &mut R) -> Self {

mavlink/tests/serde_test.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ mod serde_test {
8888
StructEnd,
8989
// u8 field
9090
Str("mavlink_version"),
91-
U8(0),
91+
U8(3),
9292
StructEnd,
9393
],
9494
);

0 commit comments

Comments
 (0)