diff --git a/build/parser.rs b/build/parser.rs index 090e0b6a2a..2dc2464053 100644 --- a/build/parser.rs +++ b/build/parser.rs @@ -514,7 +514,11 @@ impl MavMessage { // If sent by an implementation that doesn't have the extensions fields // then the recipient will see zero values for the extensions fields. let serde_default = if field.is_extension { - quote!(#[cfg_attr(feature = "serde", serde(default))]) + if field.enumtype.is_some() { + quote!(#[cfg_attr(feature = "serde", serde(default))]) + } else { + quote!(#[cfg_attr(feature = "serde", serde(default = "crate::RustDefault::rust_default"))]) + } } else { quote!() }; diff --git a/src/lib.rs b/src/lib.rs index 3ab42ac8af..5186bd8e76 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -37,7 +37,7 @@ pub use self::connection::{connect, MavConnection}; mod utils; #[allow(unused_imports)] -use utils::remove_trailing_zeroes; +use utils::{remove_trailing_zeroes, RustDefault}; #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; diff --git a/src/utils.rs b/src/utils.rs index 1b814023bc..8cbd522c7f 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -17,3 +17,95 @@ pub(crate) fn remove_trailing_zeroes(data: &mut [u8]) -> usize { len } + +/// A trait very similar to `Default` but is only implemented for the equivalent Rust types to +/// `MavType`s. This is only needed because rust doesn't currently implement `Default` for arrays +/// of all sizes. In particular this trait is only ever used when the "serde" feature is enabled. +pub(crate) trait RustDefault: Copy { + fn rust_default() -> Self; +} + +impl RustDefault for [T; N] { + #[inline(always)] + fn rust_default() -> Self { + let val: T = RustDefault::rust_default(); + [val; N] + } +} + +impl RustDefault for u8 { + #[inline(always)] + fn rust_default() -> Self { + 0 + } +} + +impl RustDefault for i8 { + #[inline(always)] + fn rust_default() -> Self { + 0 + } +} + +impl RustDefault for u16 { + #[inline(always)] + fn rust_default() -> Self { + 0 + } +} + +impl RustDefault for i16 { + #[inline(always)] + fn rust_default() -> Self { + 0 + } +} + +impl RustDefault for u32 { + #[inline(always)] + fn rust_default() -> Self { + 0 + } +} + +impl RustDefault for i32 { + #[inline(always)] + fn rust_default() -> Self { + 0 + } +} + +impl RustDefault for u64 { + #[inline(always)] + fn rust_default() -> Self { + 0 + } +} + +impl RustDefault for i64 { + #[inline(always)] + fn rust_default() -> Self { + 0 + } +} + +impl RustDefault for char { + #[inline(always)] + fn rust_default() -> Self { + '\0' + } +} + +impl RustDefault for f32 { + #[inline(always)] + fn rust_default() -> Self { + 0.0 + } +} + +impl RustDefault for f64 { + #[inline(always)] + fn rust_default() -> Self { + 0.0 + } +}